pax_global_header00006660000000000000000000000064141772660140014522gustar00rootroot0000000000000052 comment=a5569d0f49e0a889ca8b31cffe594295400d3a2b aggdraw-1.3.14/000077500000000000000000000000001417726601400132245ustar00rootroot00000000000000aggdraw-1.3.14/.github/000077500000000000000000000000001417726601400145645ustar00rootroot00000000000000aggdraw-1.3.14/.github/workflows/000077500000000000000000000000001417726601400166215ustar00rootroot00000000000000aggdraw-1.3.14/.github/workflows/ci.yml000066400000000000000000000043611417726601400177430ustar00rootroot00000000000000name: CI on: [push, pull_request] jobs: build: runs-on: ${{ matrix.os }} strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] BUILDMODE: [CIBUILDWHEEL, UNITTEST] steps: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 - name: Set up QEMU if: ${{ matrix.os == 'ubuntu-latest' && matrix.BUILDMODE == 'CIBUILDWHEEL' }} id: qemu uses: docker/setup-qemu-action@v1 - name: Setup Conda Environment if: ${{ matrix.BUILDMODE == 'UNITTEST' }} uses: conda-incubator/setup-miniconda@v2 with: miniforge-variant: Mambaforge miniforge-version: latest use-mamba: true python-version: ${{ matrix.python-version }} environment-file: ci/environment.yaml activate-environment: test-environment - name: Run tests if: ${{ matrix.BUILDMODE == 'UNITTEST' }} shell: bash -l {0} run: | pip install -e . python selftest.py - name: Build wheel if: ${{ matrix.BUILDMODE == 'CIBUILDWHEEL' }} env: CIBW_TEST_COMMAND: python {project}/selftest.py CIBW_BEFORE_BUILD_LINUX: yum install -y freetype-devel CIBW_SKIP: pp* *-musllinux* CIBW_TEST_REQUIRES: numpy pillow pytest CIBW_ARCHS_LINUX: auto aarch64 run: | python -m pip install cibuildwheel cibuildwheel --output-dir wheelhouse - name: upload if: ${{ matrix.BUILDMODE == 'CIBUILDWHEEL' }} uses: actions/upload-artifact@v2 with: name: wheelhouse path: "wheelhouse/*.whl" publish: runs-on: ubuntu-latest needs: - build steps: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 - name: sdist run: python setup.py sdist - name: download uses: actions/download-artifact@v2 with: name: wheelhouse path: dist - name: Publish package to PyPI if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/v') uses: pypa/gh-action-pypi-publish@v1.4.1 with: user: __token__ password: ${{ secrets.pypi_password }} aggdraw-1.3.14/.gitignore000066400000000000000000000034761417726601400152260ustar00rootroot00000000000000# Created by .ignore support plugin (hsz.mobi) ### C++ template # Prerequisites *.d # Compiled Object files *.slo *.lo *.o *.obj # Precompiled Headers *.gch *.pch # Compiled Dynamic libraries *.so *.dylib *.dll # Fortran module files *.mod *.smod # Compiled Static libraries *.lai *.la *.a *.lib # Executables *.exe *.out *.app ### C template # Prerequisites # Object files *.ko *.elf # Linker output *.ilk *.map *.exp # Precompiled Headers # Libraries # Shared objects (inc. Windows DLLs) *.so.* # Executables *.i*86 *.x86_64 *.hex # Debug files *.dSYM/ *.su *.idb *.pdb # Kernel Module Compile Results *.mod* *.cmd modules.order Module.symvers Mkfile.old dkms.conf ### Python template # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions # Distribution / packaging .Python env/ build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ *.egg-info/ .installed.cfg *.egg # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *,cover .hypothesis/ # Translations *.mo *.pot # Django stuff: *.log local_settings.py # Flask stuff: instance/ .webassets-cache # Scrapy stuff: .scrapy # Sphinx documentation docs/_build/ # PyBuilder target/ # Jupyter Notebook .ipynb_checkpoints # pyenv .python-version # celery beat schedule file celerybeat-schedule # SageMath parsed files *.sage.py # dotenv .env # virtualenv .venv venv/ ENV/ # Spyder project settings .spyderproject # Rope project settings .ropeproject # PyCharm project settings .idea/ # distutils MANIFEST MANIFEST aggdraw-1.3.14/CHANGELOG.md000066400000000000000000000074001417726601400150360ustar00rootroot00000000000000# The aggdraw Library ## Version 1.3.14 - Rebuild for missing Windows wheels ## Version 1.3.13 - Rebuild for python 3.10 wheels and switch to GitHub Actions ## Version 1.3.12 - Rebuild for python 3.8 wheels ## Version 1.3.11 - Force rebuild to fix freetype linking in OSX wheels ## Version 1.3.10 - Fix Draw.path docstring mentioning unused x/y coordinates - Fix compilation on OSX 10.9+ ## Version 1.3.9 - Add docstrings to public functions from original effbot documentation ## Version 1.3.8 - Force rebuild to get working linux wheels ## Version 1.3.7 - Add binary wheel building ## Version 1.3.6 - Fix Freetype linking on Linux with no freetype-config ## Version 1.3.5 - Fix Freetype linking on Windows by using ctypes ## Version 1.3.4 - Fix Freetype linking on certain systems [#27] ## Version 1.3.3 - Fix Windows compatibility [#25] ## Version 1.3.2 - Fix segmentation fault with certain compilers [#22] ## Version 1.3.1 - Fix Python 2 compatibility when getting RGB from string colors [#21] - Re-add ability to get colors from PIL [#21] ## Version 1.3.0 - Python 3 support added - Use freetype-config to find root freetype directory - REVIVE THE PROJECT! ## Changes from release 1.1 to 1.2 (1.2a3 released) - Fixed crash when using type() or help() on aggdraw objects. - Fixed crash in Path() constructor. - Fixed some build issues under recent GCC versions. The compiler still issues more warnings than it should; I'll have to fix that in a future release. (1.2a2 released) - Changed 'expose' method to require keyword arguments. You can use 'hwnd' to pass in a window handle, or 'hdc' to pass in a device context: dib.expose(hwnd=window) dib.expose(hdc=dc) - Added 'clear' method. By default, it fills the entire image to the original background color. If you pass in a color name, it uses the given color instead. (1.2a1 released) - Added experimental 'Dib' support (based on code from the Python Imaging Library). The 'Dib' factory is similar to 'Draw', but allows the drawing context to be copied to the display. dib = Dib("RGB", size, background) ... draw ... dib.expose(hwnd=wnd) - Fixed a couple of gcc compiler nits. ## Changes from release 1.0 to 1.1 (1.1 released) - Fixed rendering of symbols containing nested polygons (broken in 1.1b3). - Added 'coords' method to the Path type. This returns the current path as a polyline. If the path consists of multiple path fragments, the return value is undefined. (experimental) (1.1b3 released) - The Windows installer now uses Freetype 2.1.10. This seems to fix the issue with irregular baselines reported for some fonts. - Performance: changes to how and when drawing adapters are created, and proper clipping in the rasterizer can result in massive speedups for some applications. - Added experimental 'setantialias' method to the drawing context. Pass in 0 to disable antialiasing, 1 to enable it. Antialiasing is enabled by default. - Adjust the size of filled objects (including polygons) depending on the pen width. If no pen is used, filled antialiased objects are expanded by a half pixel, to avoid banding. If a pen is used, the objects are shrunk by a half pen width. (experimental) (1.1b2 released; internal release only) - Fixed background color bug for non-RGBA images. The third argument to the Draw constructor now works properly for all modes. - Fixed big resource leak in the Draw(im) constructor. The alternate form (Draw(mode, size)) does not leak (reported by H�kan Karlsson). - Added Path object. Path objects can be used instead of coordinates with the 'line' and 'polygon' primitives. Path objects can also be used as symbols. (1.1b1 released) - Use ImageColor.getrgb to resolve colors, if available. (1.0 final released) aggdraw-1.3.14/CODEOWNERS000066400000000000000000000002271417726601400146200ustar00rootroot00000000000000# https://github.com/blog/2392-introducing-code-owners # These owners will be the default owners for everything in the repo. * @mraspaud @davidh-ssec aggdraw-1.3.14/LICENSE.txt000066400000000000000000000035021417726601400150470ustar00rootroot00000000000000The aggdraw interface, and associated modules and documentation are: Copyright (c) 2011-2018 by AggDraw Developers Copyright (c) 2003-2006 by Secret Labs AB Copyright (c) 2003-2006 by Fredrik Lundh By obtaining, using, and/or copying this software and/or its associated documentation, you agree that you have read, understood, and will comply with the following terms and conditions: Permission to use, copy, modify, and distribute this software and its associated documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appears in all copies, and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of Secret Labs AB or the author not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. The AggDraw repository and source distributions bundle other libraries that are compatibly license. We list these here. Name: Anti-Grain Geometry - Version 2.0 Files: agg2/* Copyright (c) 2002 Maxim Shemanarev (McSeem) Permission to copy, use, modify, sell and distribute this software is granted provided this copyright notice appears in all copies. This software is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose.aggdraw-1.3.14/MANIFEST.in000066400000000000000000000001401417726601400147550ustar00rootroot00000000000000include aggdraw.cxx include LICENSE.txt recursive-include agg2 *.cpp recursive-include agg2 *.h aggdraw-1.3.14/PKG-INFO000066400000000000000000000012761417726601400143270ustar00rootroot00000000000000Metadata-Version: 1.0 Name: aggdraw Version: 1.2a3-20060212 Summary: High quality drawing interface for PIL. Home-page: http://www.effbot.org/zone/aggdraw.htm Author: Fredrik Lundh Author-email: fredrik@pythonware.com License: Python (MIT style) Download-URL: http://www.effbot.org/downloads#aggdraw Description: The aggdraw module implements the basic WCK 2D Drawing Interface on top of the AGG library. This library provides high-quality drawing, with anti-aliasing and alpha compositing, while being fully compatible with the WCK renderer. Platform: Python 2.1 and later. Classifier: Development Status :: 4 - Beta Classifier: Topic :: Multimedia :: Graphics aggdraw-1.3.14/README.rst000066400000000000000000000065571417726601400147300ustar00rootroot00000000000000================== The aggdraw module ================== .. image:: https://github.com/pytroll/aggdraw/workflows/CI/badge.svg?branch=main :target: https://github.com/pytroll/aggdraw/actions?query=workflow%3A%22CI%22 A high-quality graphics engine for PIL, based on Maxim Shemanarev's Anti-Grain Geometry library (from http://antigrain.com). The necessary AGG sources are included in the aggdraw source kit. For posterity, reference `the old documentation `_. Build instructions (all platforms) ---------------------------------- 1. Check prerequisites. You need a C++ compiler to build this extension. The library comes with the necessary AGG sources included. The following additional libraries can be used: * OpenType/TrueType support - freetype2 (2.1.10 or later is recommended) See http://www.freetype.org and http://freetype.sourceforge.net for details. 2. Configure. To enable freetype, you need to build the library somewhere and make sure the `freetype-config` command is available on your PATH. The setup.py file will call `freetype-config --prefix` to locate all of the necessary libraries and headers. 3. Build. The library uses a standard setup.py file, and you can use all standard setup.py commands. I recommend the following steps:: $ python setup.py build_ext -i $ python selftest.py (if you're lazy, you can skip the above and just install the library; setup.py will make sure the right stuff is built before it's installed). 4. Install. If the selftest succeeds, you can install the library:: $ python setup.py install 5. Enjoy! AGG2 License ------------ Anti-Grain Geometry - Version 2.0 Copyright (c) 2002 Maxim Shemanarev (McSeem) Permission to copy, use, modify, sell and distribute this software is granted provided this copyright notice appears in all copies. This software is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose. AggDraw License --------------- The aggdraw interface, and associated modules and documentation are: Copyright (c) 2011-2017 by AGGDraw Developers Copyright (c) 2003-2006 by Secret Labs AB Copyright (c) 2003-2006 by Fredrik Lundh By obtaining, using, and/or copying this software and/or its associated documentation, you agree that you have read, understood, and will comply with the following terms and conditions: Permission to use, copy, modify, and distribute this software and its associated documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appears in all copies, and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of Secret Labs AB or the author not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. aggdraw-1.3.14/agg2/000077500000000000000000000000001417726601400140445ustar00rootroot00000000000000aggdraw-1.3.14/agg2/README.txt000066400000000000000000000007471417726601400155520ustar00rootroot00000000000000 The Anti-Grain Geometry Project A high quality rendering engine for C++ http://antigrain.com Anti-Grain Geometry - Version 2.0 Copyright (C) 2002 Maxim Shemanarev (McSeem) Permission to copy, use, modify, sell and distribute this software is granted provided this copyright notice appears in all copies. This software is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose. TODO: write compilation/installation stuff aggdraw-1.3.14/agg2/font_freetype/000077500000000000000000000000001417726601400167155ustar00rootroot00000000000000aggdraw-1.3.14/agg2/font_freetype/agg_font_freetype.cpp000066400000000000000000001104411417726601400231110ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #include #include "agg_font_freetype.h" #include "agg_bitset_iterator.h" #include "agg_renderer_scanline.h" namespace agg { //------------------------------------------------------------------------------ // // This code implements the AUTODIN II polynomial // The variable corresponding to the macro argument "crc" should // be an unsigned long. // Oroginal code by Spencer Garrett // // generated using the AUTODIN II polynomial // x^32 + x^26 + x^23 + x^22 + x^16 + // x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1 // //------------------------------------------------------------------------------ static const unsigned crc32tab[256] = { 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, }; //------------------------------------------------------------------------------ static unsigned calc_crc32(const unsigned char* buf, unsigned size) { unsigned crc = (unsigned)~0; const unsigned char* p; unsigned len = 0; unsigned nr = size; for (len += nr, p = buf; nr--; ++p) { crc = (crc >> 8) ^ crc32tab[(crc ^ *p) & 0xff]; } return ~crc; } //------------------------------------------------------------------------ inline double conv_coord_64(int v) { return double(v) / 64.0; } //------------------------------------------------------------------------ inline int conv_coord_none(int v) { return v; } //------------------------------------------------------------------------ template bool decompose_ft_outline(const FT_Outline& outline, bool flip_y, PathStorage& path, ConvCoord conv) { FT_Vector v_last; FT_Vector v_control; FT_Vector v_start; FT_Vector* point; FT_Vector* limit; char* tags; int n; // index of contour in outline int first; // index of first point in contour char tag; // current point's state first = 0; for(n = 0; n < outline.n_contours; n++) { int last; // index of last point in contour last = outline.contours[n]; limit = outline.points + last; 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) return false; // 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--; } path.move_to(conv(v_start.x), flip_y ? -conv(v_start.y) : conv(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 { path.line_to(conv(point->x), flip_y ? -conv(point->y) : conv(point->y)); 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.x = point->x; vec.y = point->y; if(tag == FT_CURVE_TAG_ON) { path.curve3(conv(v_control.x), flip_y ? -conv(v_control.y) : conv(v_control.y), conv(vec.x), flip_y ? -conv(vec.y) : conv(vec.y)); continue; } if(tag != FT_CURVE_TAG_CONIC) return false; v_middle.x = (v_control.x + vec.x) / 2; v_middle.y = (v_control.y + vec.y) / 2; path.curve3(conv(v_control.x), flip_y ? -conv(v_control.y) : conv(v_control.y), conv(v_middle.x), flip_y ? -conv(v_middle.y) : conv(v_middle.y)); v_control = vec; goto Do_Conic; } path.curve3(conv(v_control.x), flip_y ? -conv(v_control.y) : conv(v_control.y), conv(v_start.x), flip_y ? -conv(v_start.y) : conv(v_start.y)); goto Close; } default: // FT_CURVE_TAG_CUBIC { FT_Vector vec1, vec2; if(point + 1 > limit || FT_CURVE_TAG(tags[1]) != FT_CURVE_TAG_CUBIC) { return false; } vec1.x = point[0].x; vec1.y = point[0].y; vec2.x = point[1].x; vec2.y = point[1].y; point += 2; tags += 2; if(point <= limit) { FT_Vector vec; vec.x = point->x; vec.y = point->y; path.curve4(conv(vec1.x), flip_y ? -conv(vec1.y) : conv(vec1.y), conv(vec2.x), flip_y ? -conv(vec2.y) : conv(vec2.y), conv(vec.x), flip_y ? -conv(vec.y) : conv(vec.y)); continue; } path.curve4(conv(vec1.x), flip_y ? -conv(vec1.y) : conv(vec1.y), conv(vec2.x), flip_y ? -conv(vec2.y) : conv(vec2.y), conv(v_start.x), flip_y ? -conv(v_start.y) : conv(v_start.y)); goto Close; } } } path.close_polygon(); Close: first = last + 1; } return true; } //------------------------------------------------------------------------ template void decompose_ft_bitmap_mono(const FT_Bitmap& bitmap, int x, int y, bool flip_y, Scanline& sl, ScanlineStorage& storage) { int i; const int8u* buf = (const int8u*)bitmap.buffer; int pitch = bitmap.pitch; sl.reset(x, x + bitmap.width); storage.prepare(bitmap.width + 2); if(flip_y) { buf += bitmap.pitch * (bitmap.rows - 1); y += bitmap.rows; pitch = -pitch; } for(i = 0; i < bitmap.rows; i++) { sl.reset_spans(); bitset_iterator bits(buf, 0); int j; for(j = 0; j < bitmap.width; j++) { if(bits.bit()) sl.add_cell(x + j, cover_full); ++bits; } buf += pitch; if(sl.num_spans()) { sl.finalize(y - i - 1); storage.render(sl); } } } //------------------------------------------------------------------------ template void decompose_ft_bitmap_gray8(const FT_Bitmap& bitmap, int x, int y, bool flip_y, Rasterizer& ras, Scanline& sl, ScanlineStorage& storage) { int i, j; const int8u* buf = (const int8u*)bitmap.buffer; int pitch = bitmap.pitch; sl.reset(x, x + bitmap.width); storage.prepare(bitmap.width + 2); if(flip_y) { buf += bitmap.pitch * (bitmap.rows - 1); y += bitmap.rows; pitch = -pitch; } for(i = 0; i < bitmap.rows; i++) { sl.reset_spans(); const int8u* p = buf; for(j = 0; j < bitmap.width; j++) { if(*p) sl.add_cell(x + j, ras.apply_gamma(*p)); ++p; } buf += pitch; if(sl.num_spans()) { sl.finalize(y - i - 1); storage.render(sl); } } } //------------------------------------------------------------------------ font_engine_freetype_base::~font_engine_freetype_base() { unsigned i; for(i = 0; i < m_num_faces; ++i) { delete [] m_face_names[i]; FT_Done_Face(m_faces[i]); } delete [] m_face_names; delete [] m_faces; delete [] m_signature; if(m_library_initialized) FT_Done_FreeType(m_library); } //------------------------------------------------------------------------ font_engine_freetype_base::font_engine_freetype_base(bool flag32, unsigned max_faces) : m_flag32(flag32), m_change_stamp(0), m_last_error(0), m_name(0), m_name_len(256-16-1), m_face_index(0), m_char_map(FT_ENCODING_NONE), m_signature(new char [256+256-16]), m_height(0), m_width(0), m_hinting(true), m_flip_y(false), m_library_initialized(false), m_library(0), m_faces(new FT_Face [max_faces]), m_face_names(new char* [max_faces]), m_num_faces(0), m_max_faces(max_faces), m_cur_face(0), m_resolution(0), m_glyph_rendering(glyph_ren_native_gray8), m_glyph_index(0), m_data_size(0), m_data_type(glyph_data_invalid), m_bounds(1,1,0,0), m_advance_x(0.0), m_advance_y(0.0), m_path16(), m_path32(), m_curves16(m_path16), m_curves32(m_path32), m_scanline_aa(), m_scanline_bin(), m_scanlines_aa(), m_scanlines_bin(), m_rasterizer() { m_matrix.xx = 0x10000L; m_matrix.xy = 0; m_matrix.yx = 0; m_matrix.yy = 0x10000L; m_curves16.approximation_scale(4.0); m_curves32.approximation_scale(4.0); m_last_error = FT_Init_FreeType(&m_library); if(m_last_error == 0) m_library_initialized = true; } //------------------------------------------------------------------------ void font_engine_freetype_base::resolution(unsigned dpi) { m_resolution = dpi; update_char_size(); } //------------------------------------------------------------------------ int font_engine_freetype_base::find_face(const char* face_name) const { unsigned i; for(i = 0; i < m_num_faces; ++i) { if(strcmp(face_name, m_face_names[i]) == 0) return i; } return -1; } //------------------------------------------------------------------------ bool font_engine_freetype_base::load_font(const char* font_name, unsigned face_index, glyph_rendering ren_type) { bool ret = false; if(m_library_initialized) { m_last_error = 0; int idx = find_face(font_name); if(idx >= 0) { m_cur_face = m_faces[idx]; m_name = m_face_names[idx]; } else { if(m_num_faces >= m_max_faces) { delete [] m_face_names[0]; FT_Done_Face(m_faces[0]); memcpy(m_faces, m_faces + 1, (m_max_faces - 1) * sizeof(FT_Face)); memcpy(m_face_names, m_face_names + 1, (m_max_faces - 1) * sizeof(char*)); m_num_faces = m_max_faces - 1; } m_last_error = FT_New_Face(m_library, font_name, face_index, &m_faces[m_num_faces]); if(m_last_error == 0) { m_face_names[m_num_faces] = new char [strlen(font_name) + 1]; strcpy(m_face_names[m_num_faces], font_name); m_cur_face = m_faces[m_num_faces]; m_name = m_face_names[m_num_faces]; ++m_num_faces; } else { m_face_names[m_num_faces] = 0; m_cur_face = 0; m_name = 0; } } if(m_last_error == 0) { ret = true; switch(ren_type) { case glyph_ren_native_mono: m_glyph_rendering = glyph_ren_native_mono; break; case glyph_ren_native_gray8: m_glyph_rendering = glyph_ren_native_gray8; break; case glyph_ren_outline: if(FT_IS_SCALABLE(m_cur_face)) { m_glyph_rendering = glyph_ren_outline; } else { m_glyph_rendering = glyph_ren_native_gray8; } break; case glyph_ren_agg_mono: if(FT_IS_SCALABLE(m_cur_face)) { m_glyph_rendering = glyph_ren_agg_mono; } else { m_glyph_rendering = glyph_ren_native_mono; } break; case glyph_ren_agg_gray8: if(FT_IS_SCALABLE(m_cur_face)) { m_glyph_rendering = glyph_ren_agg_gray8; } else { m_glyph_rendering = glyph_ren_native_gray8; } break; } update_transform(); } } return ret; } //------------------------------------------------------------------------ bool font_engine_freetype_base::attach(const char* file_name) { if(m_cur_face) { m_last_error = FT_Attach_File(m_cur_face, file_name); return m_last_error == 0; } return false; } //------------------------------------------------------------------------ unsigned font_engine_freetype_base::num_faces() const { if(m_cur_face) { return m_cur_face->num_faces; } return 0; } //------------------------------------------------------------------------ bool font_engine_freetype_base::char_map(FT_Encoding char_map) { if(m_cur_face) { m_last_error = FT_Select_Charmap(m_cur_face, m_char_map); if(m_last_error == 0) { update_signature(); return true; } } return false; } //------------------------------------------------------------------------ bool font_engine_freetype_base::height(double h) { m_height = int(h * 64.0); if(m_cur_face) { update_char_size(); return true; } return false; } //------------------------------------------------------------------------ bool font_engine_freetype_base::width(double w) { m_width = int(w * 64.0); if(m_cur_face) { update_char_size(); return true; } return false; } //------------------------------------------------------------------------ void font_engine_freetype_base::update_transform() { FT_Matrix mtx = m_matrix; if(m_flip_y) { mtx.xy = -mtx.xy; mtx.yy = -mtx.yy; } if(m_cur_face) { FT_Vector pen; pen.x = 0; pen.y = 0; FT_Set_Transform(m_cur_face, &mtx, &pen); update_signature(); } } //------------------------------------------------------------------------ void font_engine_freetype_base::transform(const trans_affine& mtx) { double m[6]; mtx.store_to(m); m_matrix.xx = long( m[0] * 0x10000L); m_matrix.xy = long(-m[1] * 0x10000L); m_matrix.yx = long(-m[2] * 0x10000L); m_matrix.yy = long( m[3] * 0x10000L); update_transform(); } //------------------------------------------------------------------------ void font_engine_freetype_base::transform(double xx, double xy, double yx, double yy) { m_matrix.xx = long( xx * 0x10000L); m_matrix.xy = long(-xy * 0x10000L); m_matrix.yx = long(-yx * 0x10000L); m_matrix.yy = long( yy * 0x10000L); update_transform(); } //------------------------------------------------------------------------ void font_engine_freetype_base::hinting(bool h) { m_hinting = h; if(m_cur_face) { update_signature(); } } //------------------------------------------------------------------------ void font_engine_freetype_base::flip_y(bool f) { m_flip_y = f; if(m_cur_face) { update_transform(); } } //------------------------------------------------------------------------ void font_engine_freetype_base::update_signature() { if(m_cur_face && m_name) { unsigned name_len = strlen(m_name); if(name_len > m_name_len) { delete [] m_signature; m_signature = new char [name_len + 32 + 256]; m_name_len = name_len + 32 - 1; } unsigned gamma_hash = 0; if(m_glyph_rendering == glyph_ren_native_gray8 || m_glyph_rendering == glyph_ren_agg_mono || m_glyph_rendering == glyph_ren_agg_gray8) { unsigned char gamma_table[rasterizer_scanline_aa<>::aa_num]; unsigned i; for(i = 0; i < rasterizer_scanline_aa<>::aa_num; ++i) { gamma_table[i] = m_rasterizer.apply_gamma(i); } gamma_hash = calc_crc32(gamma_table, sizeof(gamma_table)); } sprintf(m_signature, "%s,%u,%d,%d,%d:%dx%d,%d,%d,%d,%d,%d,%d,%08X", m_name, m_char_map, m_face_index, int(m_glyph_rendering), m_resolution, m_height, m_width, m_matrix.xx, m_matrix.xy, m_matrix.yx, m_matrix.yy, int(m_hinting), int(m_flip_y), gamma_hash); ++m_change_stamp; } } //------------------------------------------------------------------------ void font_engine_freetype_base::update_char_size() { if(m_cur_face) { if(m_resolution) { FT_Set_Char_Size(m_cur_face, m_width, // char_width in 1/64th of points m_height, // char_height in 1/64th of points m_resolution, // horizontal device resolution m_resolution); // vertical device resolution } else { FT_Set_Pixel_Sizes(m_cur_face, m_width >> 6, // pixel_width m_height >> 6); // pixel_height } update_signature(); } } //------------------------------------------------------------------------ bool font_engine_freetype_base::prepare_glyph(unsigned glyph_code) { bool flip = false; m_glyph_index = FT_Get_Char_Index(m_cur_face, glyph_code); m_last_error = FT_Load_Glyph(m_cur_face, m_glyph_index, m_hinting ? FT_LOAD_DEFAULT : FT_LOAD_NO_HINTING); // m_hinting ? FT_LOAD_FORCE_AUTOHINT : FT_LOAD_NO_HINTING); if(m_last_error == 0) { switch(m_glyph_rendering) { case glyph_ren_native_mono: m_last_error = FT_Render_Glyph(m_cur_face->glyph, FT_RENDER_MODE_MONO); if(m_last_error == 0) { decompose_ft_bitmap_mono(m_cur_face->glyph->bitmap, m_cur_face->glyph->bitmap_left, flip ? -m_cur_face->glyph->bitmap_top : m_cur_face->glyph->bitmap_top, flip, m_scanline_bin, m_scanlines_bin); m_bounds.x1 = m_scanlines_bin.min_x(); m_bounds.y1 = m_scanlines_bin.min_y(); m_bounds.x2 = m_scanlines_bin.max_x(); m_bounds.y2 = m_scanlines_bin.max_y(); m_data_size = m_scanlines_bin.byte_size(); m_data_type = glyph_data_mono; m_advance_x = double(m_cur_face->glyph->advance.x) / 64.0; m_advance_y = double(m_cur_face->glyph->advance.y) / 64.0; return true; } break; case glyph_ren_native_gray8: m_last_error = FT_Render_Glyph(m_cur_face->glyph, FT_RENDER_MODE_NORMAL); if(m_last_error == 0) { decompose_ft_bitmap_gray8(m_cur_face->glyph->bitmap, m_cur_face->glyph->bitmap_left, flip ? -m_cur_face->glyph->bitmap_top : m_cur_face->glyph->bitmap_top, flip, m_rasterizer, m_scanline_aa, m_scanlines_aa); m_bounds.x1 = m_scanlines_aa.min_x(); m_bounds.y1 = m_scanlines_aa.min_y(); m_bounds.x2 = m_scanlines_aa.max_x(); m_bounds.y2 = m_scanlines_aa.max_y(); m_data_size = m_scanlines_aa.byte_size(); m_data_type = glyph_data_gray8; m_advance_x = double(m_cur_face->glyph->advance.x) / 64.0; m_advance_y = double(m_cur_face->glyph->advance.y) / 64.0; return true; } break; case glyph_ren_outline: if(m_last_error == 0) { if(m_flag32) { m_path32.remove_all(); if(decompose_ft_outline(m_cur_face->glyph->outline, flip, m_path32, conv_coord_none)) { rect_d bnd = m_path32.bounding_rect(); m_data_size = m_path32.byte_size(); m_data_type = glyph_data_outline; m_bounds.x1 = int(floor(bnd.x1)); m_bounds.y1 = int(floor(bnd.y1)); m_bounds.x2 = int(ceil(bnd.x2)); m_bounds.y2 = int(ceil(bnd.y2)); m_advance_x = double(m_cur_face->glyph->advance.x) / 64.0; m_advance_y = double(m_cur_face->glyph->advance.y) / 64.0; return true; } } else { m_path16.remove_all(); if(decompose_ft_outline(m_cur_face->glyph->outline, flip, m_path16, conv_coord_none)) { rect_d bnd = m_path16.bounding_rect(); m_data_size = m_path16.byte_size(); m_data_type = glyph_data_outline; m_bounds.x1 = int(floor(bnd.x1)); m_bounds.y1 = int(floor(bnd.y1)); m_bounds.x2 = int(ceil(bnd.x2)); m_bounds.y2 = int(ceil(bnd.y2)); m_advance_x = double(m_cur_face->glyph->advance.x) / 64.0; m_advance_y = double(m_cur_face->glyph->advance.y) / 64.0; return true; } } } return false; case glyph_ren_agg_mono: if(m_last_error == 0) { m_rasterizer.reset(); if(m_flag32) { m_path32.remove_all(); decompose_ft_outline(m_cur_face->glyph->outline, flip, m_path32, conv_coord_none); m_rasterizer.add_path(m_curves32); } else { m_path16.remove_all(); decompose_ft_outline(m_cur_face->glyph->outline, flip, m_path16, conv_coord_none); m_rasterizer.add_path(m_curves16); } m_scanlines_bin.prepare(1); // Remove all render_scanlines(m_rasterizer, m_scanline_bin, m_scanlines_bin); m_bounds.x1 = m_scanlines_bin.min_x(); m_bounds.y1 = m_scanlines_bin.min_y(); m_bounds.x2 = m_scanlines_bin.max_x(); m_bounds.y2 = m_scanlines_bin.max_y(); m_data_size = m_scanlines_bin.byte_size(); m_data_type = glyph_data_mono; m_advance_x = double(m_cur_face->glyph->advance.x) / 64.0; m_advance_y = double(m_cur_face->glyph->advance.y) / 64.0; return true; } return false; case glyph_ren_agg_gray8: if(m_last_error == 0) { m_rasterizer.reset(); if(m_flag32) { m_path32.remove_all(); decompose_ft_outline(m_cur_face->glyph->outline, flip, m_path32, conv_coord_none); m_rasterizer.add_path(m_curves32); } else { m_path16.remove_all(); decompose_ft_outline(m_cur_face->glyph->outline, flip, m_path16, conv_coord_none); m_rasterizer.add_path(m_curves16); } m_scanlines_aa.prepare(1); // Remove all render_scanlines(m_rasterizer, m_scanline_aa, m_scanlines_aa); m_bounds.x1 = m_scanlines_aa.min_x(); m_bounds.y1 = m_scanlines_aa.min_y(); m_bounds.x2 = m_scanlines_aa.max_x(); m_bounds.y2 = m_scanlines_aa.max_y(); m_data_size = m_scanlines_aa.byte_size(); m_data_type = glyph_data_gray8; m_advance_x = double(m_cur_face->glyph->advance.x) / 64.0; m_advance_y = double(m_cur_face->glyph->advance.y) / 64.0; return true; } return false; } } return false; } //------------------------------------------------------------------------ void font_engine_freetype_base::write_glyph_to(int8u* data) const { if(data && m_data_size) { switch(m_data_type) { case glyph_data_mono: m_scanlines_bin.serialize(data); break; case glyph_data_gray8: m_scanlines_aa.serialize(data); break; case glyph_data_outline: if(m_flag32) { m_path32.serialize(data); } else { m_path16.serialize(data); } break; } } } //------------------------------------------------------------------------ bool font_engine_freetype_base::add_kerning(unsigned first, unsigned second, double* x, double* y) { if(m_cur_face && first && second && FT_HAS_KERNING(m_cur_face)) { FT_Vector delta; FT_Get_Kerning(m_cur_face, first, second, FT_KERNING_DEFAULT, &delta); FT_Vector_Transform(&delta, &m_matrix); *x += double(delta.x) / 64.0; *y += double(delta.y) / 64.0; return true; } return false; } } aggdraw-1.3.14/agg2/font_freetype/agg_font_freetype.h000066400000000000000000000201451417726601400225570ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // See implementation agg_font_freetype.cpp // //---------------------------------------------------------------------------- #ifndef AGG_FONT_FREETYPE_INCLUDED #define AGG_FONT_FREETYPE_INCLUDED #include #include FT_FREETYPE_H #include "agg_scanline_storage_aa.h" #include "agg_scanline_storage_bin.h" #include "agg_scanline_u.h" #include "agg_scanline_bin.h" #include "agg_path_storage_integer.h" #include "agg_rasterizer_scanline_aa.h" #include "agg_conv_curve.h" #include "agg_trans_affine.h" #include "agg_font_cache_manager.h" namespace agg { //-----------------------------------------------font_engine_freetype_base class font_engine_freetype_base { public: //-------------------------------------------------------------------- typedef serialized_scanlines_adaptor_aa gray8_adaptor_type; typedef serialized_scanlines_adaptor_bin mono_adaptor_type; typedef scanline_storage_aa8 scanlines_aa_type; typedef scanline_storage_bin scanlines_bin_type; //-------------------------------------------------------------------- ~font_engine_freetype_base(); font_engine_freetype_base(bool flag32, unsigned max_faces = 32); // Set font parameters //-------------------------------------------------------------------- void resolution(unsigned dpi); bool load_font(const char* font_name, unsigned face_index, glyph_rendering ren_type); bool attach(const char* file_name); bool char_map(FT_Encoding map); bool height(double h); bool width(double w); void transform(const trans_affine& mtx); void transform(double xx, double xy, double yx, double yy); void hinting(bool h); void flip_y(bool f); // Set Gamma //-------------------------------------------------------------------- template void gamma(const GammaF& f) { m_rasterizer.gamma(f); } // Accessors //-------------------------------------------------------------------- int last_error() const { return m_last_error; } unsigned resolution() const { return m_resolution; } const char* name() const { return m_name; } unsigned num_faces() const; FT_Encoding char_map() const { return m_char_map; } double height() const { return double(m_height) / 64.0; } double width() const { return double(m_width) / 64.0; } bool hinting() const { return m_hinting; } bool flip_y() const { return m_flip_y; } // Interface mandatory to implement for font_cache_manager //-------------------------------------------------------------------- const char* font_signature() const { return m_signature; } int change_stamp() const { return m_change_stamp; } bool prepare_glyph(unsigned glyph_code); unsigned glyph_index() const { return m_glyph_index; } unsigned data_size() const { return m_data_size; } glyph_data_type data_type() const { return m_data_type; } const rect& bounds() const { return m_bounds; } double advance_x() const { return m_advance_x; } double advance_y() const { return m_advance_y; } void write_glyph_to(int8u* data) const; bool add_kerning(unsigned first, unsigned second, double* x, double* y); private: font_engine_freetype_base(const font_engine_freetype_base&); const font_engine_freetype_base& operator = (const font_engine_freetype_base&); void update_char_size(); void update_signature(); void update_transform(); int find_face(const char* face_name) const; bool m_flag32; int m_change_stamp; int m_last_error; char* m_name; unsigned m_name_len; unsigned m_face_index; FT_Encoding m_char_map; char* m_signature; unsigned m_height; unsigned m_width; FT_Matrix m_matrix; bool m_hinting; bool m_flip_y; bool m_library_initialized; FT_Library m_library; // handle to library FT_Face* m_faces; // A pool of font faces char** m_face_names; unsigned m_num_faces; unsigned m_max_faces; public: FT_Face m_cur_face; // handle to the current face object private: int m_resolution; glyph_rendering m_glyph_rendering; unsigned m_glyph_index; unsigned m_data_size; glyph_data_type m_data_type; rect m_bounds; double m_advance_x; double m_advance_y; path_storage_integer m_path16; path_storage_integer m_path32; conv_curve > m_curves16; conv_curve > m_curves32; scanline_u8 m_scanline_aa; scanline_bin m_scanline_bin; scanlines_aa_type m_scanlines_aa; scanlines_bin_type m_scanlines_bin; rasterizer_scanline_aa<> m_rasterizer; }; //------------------------------------------------font_engine_freetype_int16 // This class uses values of type int16 (10.6 format) for the vector cache. // The vector cache is compact, but when rendering glyphs of height // more that 200 there integer overflow can occur. // class font_engine_freetype_int16 : public font_engine_freetype_base { public: typedef serialized_integer_path_adaptor path_adaptor_type; typedef font_engine_freetype_base::gray8_adaptor_type gray8_adaptor_type; typedef font_engine_freetype_base::mono_adaptor_type mono_adaptor_type; typedef font_engine_freetype_base::scanlines_aa_type scanlines_aa_type; typedef font_engine_freetype_base::scanlines_bin_type scanlines_bin_type; font_engine_freetype_int16(unsigned max_faces = 32) : font_engine_freetype_base(false, max_faces) {} }; //------------------------------------------------font_engine_freetype_int32 // This class uses values of type int32 (26.6 format) for the vector cache. // The vector cache is twice larger than in font_engine_freetype_int16, // but it allows you to render glyphs of very large sizes. // class font_engine_freetype_int32 : public font_engine_freetype_base { public: typedef serialized_integer_path_adaptor path_adaptor_type; typedef font_engine_freetype_base::gray8_adaptor_type gray8_adaptor_type; typedef font_engine_freetype_base::mono_adaptor_type mono_adaptor_type; typedef font_engine_freetype_base::scanlines_aa_type scanlines_aa_type; typedef font_engine_freetype_base::scanlines_bin_type scanlines_bin_type; font_engine_freetype_int32(unsigned max_faces = 32) : font_engine_freetype_base(true, max_faces) {} }; } #endif aggdraw-1.3.14/agg2/include/000077500000000000000000000000001417726601400154675ustar00rootroot00000000000000aggdraw-1.3.14/agg2/include/agg_alpha_mask_u8.h000066400000000000000000000436411417726601400212020ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // scanline_u8 class // //---------------------------------------------------------------------------- #ifndef AGG_ALPHA_MASK_U8_INCLUDED #define AGG_ALPHA_MASK_U8_INCLUDED #include #include "agg_basics.h" #include "agg_rendering_buffer.h" namespace agg { //===================================================one_component_mask_u8 struct one_component_mask_u8 { static unsigned calculate(const int8u* p) { return *p; } }; //=====================================================rgb_to_gray_mask_u8 template struct rgb_to_gray_mask_u8 { static unsigned calculate(const int8u* p) { return (p[R]*77 + p[G]*150 + p[B]*29) >> 8; } }; //==========================================================alpha_mask_u8 template class alpha_mask_u8 { public: typedef int8u cover_type; typedef alpha_mask_u8 self_type; enum { cover_shift = 8, cover_none = 0, cover_full = 255 }; alpha_mask_u8() : m_rbuf(0) {} alpha_mask_u8(rendering_buffer& rbuf) : m_rbuf(&rbuf) {} void attach(rendering_buffer& rbuf) { m_rbuf = &rbuf; } MaskF& mask_function() { return m_mask_function; } const MaskF& mask_function() const { return m_mask_function; } //-------------------------------------------------------------------- cover_type pixel(int x, int y) const { if(x >= 0 && y >= 0 && x < (int)m_rbuf->width() && y <= (int)m_rbuf->height()) { return (cover_type)m_mask_function.calculate( m_rbuf->row(y) + x * Step + Offset); } return 0; } //-------------------------------------------------------------------- cover_type combine_pixel(int x, int y, cover_type val) const { if(x >= 0 && y >= 0 && x < (int)m_rbuf->width() && y <= (int)m_rbuf->height()) { return (cover_type)((val * m_mask_function.calculate( m_rbuf->row(y) + x * Step + Offset)) >> cover_shift); } return 0; } //-------------------------------------------------------------------- void fill_hspan(int x, int y, cover_type* dst, int num_pix) const { int xmax = m_rbuf->width() - 1; int ymax = m_rbuf->height() - 1; int count = num_pix; cover_type* covers = dst; if(y < 0 || y > ymax) { memset(dst, 0, num_pix * sizeof(cover_type)); return; } if(x < 0) { count += x; if(count <= 0) { memset(dst, 0, num_pix * sizeof(cover_type)); return; } memset(covers, 0, -x * sizeof(cover_type)); covers -= x; x = 0; } if(x + count > xmax) { int rest = x + count - xmax - 1; count -= rest; if(count <= 0) { memset(dst, 0, num_pix * sizeof(cover_type)); return; } memset(covers + count, 0, rest * sizeof(cover_type)); } const int8u* mask = m_rbuf->row(y) + x * Step + Offset; do { *covers++ = (cover_type)m_mask_function.calculate(mask); mask += Step; } while(--count); } //-------------------------------------------------------------------- void combine_hspan(int x, int y, cover_type* dst, int num_pix) const { int xmax = m_rbuf->width() - 1; int ymax = m_rbuf->height() - 1; int count = num_pix; cover_type* covers = dst; if(y < 0 || y > ymax) { memset(dst, 0, num_pix * sizeof(cover_type)); return; } if(x < 0) { count += x; if(count <= 0) { memset(dst, 0, num_pix * sizeof(cover_type)); return; } memset(covers, 0, -x * sizeof(cover_type)); covers -= x; x = 0; } if(x + count > xmax) { int rest = x + count - xmax - 1; count -= rest; if(count <= 0) { memset(dst, 0, num_pix * sizeof(cover_type)); return; } memset(covers + count, 0, rest * sizeof(cover_type)); } const int8u* mask = m_rbuf->row(y) + x * Step + Offset; do { *covers = (cover_type)(((*covers) * m_mask_function.calculate(mask)) >> cover_shift); ++covers; mask += Step; } while(--count); } //-------------------------------------------------------------------- void fill_vspan(int x, int y, cover_type* dst, int num_pix) const { int xmax = m_rbuf->width() - 1; int ymax = m_rbuf->height() - 1; int count = num_pix; cover_type* covers = dst; if(x < 0 || x > xmax) { memset(dst, 0, num_pix * sizeof(cover_type)); return; } if(y < 0) { count += y; if(count <= 0) { memset(dst, 0, num_pix * sizeof(cover_type)); return; } memset(covers, 0, -y * sizeof(cover_type)); covers -= y; y = 0; } if(y + count > ymax) { int rest = y + count - ymax - 1; count -= rest; if(count <= 0) { memset(dst, 0, num_pix * sizeof(cover_type)); return; } memset(covers + count, 0, rest * sizeof(cover_type)); } const int8u* mask = m_rbuf->row(y) + x * Step + Offset; do { *covers++ = (cover_type)m_mask_function.calculate(mask); mask += m_rbuf->stride(); } while(--count); } //-------------------------------------------------------------------- void combine_vspan(int x, int y, cover_type* dst, int num_pix) const { int xmax = m_rbuf->width() - 1; int ymax = m_rbuf->height() - 1; int count = num_pix; cover_type* covers = dst; if(x < 0 || x > xmax) { memset(dst, 0, num_pix * sizeof(cover_type)); return; } if(y < 0) { count += y; if(count <= 0) { memset(dst, 0, num_pix * sizeof(cover_type)); return; } memset(covers, 0, -y * sizeof(cover_type)); covers -= y; y = 0; } if(y + count > ymax) { int rest = y + count - ymax - 1; count -= rest; if(count <= 0) { memset(dst, 0, num_pix * sizeof(cover_type)); return; } memset(covers + count, 0, rest * sizeof(cover_type)); } const int8u* mask = m_rbuf->row(y) + x * Step + Offset; do { *covers = (cover_type)(((*covers) * m_mask_function.calculate(mask)) >> cover_shift); ++covers; mask += m_rbuf->stride(); } while(--count); } private: alpha_mask_u8(const self_type&); const self_type& operator = (const self_type&); rendering_buffer* m_rbuf; MaskF m_mask_function; }; typedef alpha_mask_u8<1, 0> alpha_mask_gray8; //----alpha_mask_gray8 typedef alpha_mask_u8<3, 0> alpha_mask_rgb24r; //----alpha_mask_rgb24r typedef alpha_mask_u8<3, 1> alpha_mask_rgb24g; //----alpha_mask_rgb24g typedef alpha_mask_u8<3, 2> alpha_mask_rgb24b; //----alpha_mask_rgb24b typedef alpha_mask_u8<3, 2> alpha_mask_bgr24r; //----alpha_mask_bgr24r typedef alpha_mask_u8<3, 1> alpha_mask_bgr24g; //----alpha_mask_bgr24g typedef alpha_mask_u8<3, 0> alpha_mask_bgr24b; //----alpha_mask_bgr24b typedef alpha_mask_u8<4, 0> alpha_mask_rgba32r; //----alpha_mask_rgba32r typedef alpha_mask_u8<4, 1> alpha_mask_rgba32g; //----alpha_mask_rgba32g typedef alpha_mask_u8<4, 2> alpha_mask_rgba32b; //----alpha_mask_rgba32b typedef alpha_mask_u8<4, 3> alpha_mask_rgba32a; //----alpha_mask_rgba32a typedef alpha_mask_u8<4, 1> alpha_mask_argb32r; //----alpha_mask_argb32r typedef alpha_mask_u8<4, 2> alpha_mask_argb32g; //----alpha_mask_argb32g typedef alpha_mask_u8<4, 3> alpha_mask_argb32b; //----alpha_mask_argb32b typedef alpha_mask_u8<4, 0> alpha_mask_argb32a; //----alpha_mask_argb32a typedef alpha_mask_u8<4, 2> alpha_mask_bgra32r; //----alpha_mask_bgra32r typedef alpha_mask_u8<4, 1> alpha_mask_bgra32g; //----alpha_mask_bgra32g typedef alpha_mask_u8<4, 0> alpha_mask_bgra32b; //----alpha_mask_bgra32b typedef alpha_mask_u8<4, 3> alpha_mask_bgra32a; //----alpha_mask_bgra32a typedef alpha_mask_u8<4, 3> alpha_mask_abgr32r; //----alpha_mask_abgr32r typedef alpha_mask_u8<4, 2> alpha_mask_abgr32g; //----alpha_mask_abgr32g typedef alpha_mask_u8<4, 1> alpha_mask_abgr32b; //----alpha_mask_abgr32b typedef alpha_mask_u8<4, 0> alpha_mask_abgr32a; //----alpha_mask_abgr32a typedef alpha_mask_u8<3, 0, rgb_to_gray_mask_u8<0, 1, 2> > alpha_mask_rgb24gray; //----alpha_mask_rgb24gray typedef alpha_mask_u8<3, 0, rgb_to_gray_mask_u8<2, 1, 0> > alpha_mask_bgr24gray; //----alpha_mask_bgr24gray typedef alpha_mask_u8<4, 0, rgb_to_gray_mask_u8<0, 1, 2> > alpha_mask_rgba32gray; //----alpha_mask_rgba32gray typedef alpha_mask_u8<4, 1, rgb_to_gray_mask_u8<0, 1, 2> > alpha_mask_argb32gray; //----alpha_mask_argb32gray typedef alpha_mask_u8<4, 0, rgb_to_gray_mask_u8<2, 1, 0> > alpha_mask_bgra32gray; //----alpha_mask_bgra32gray typedef alpha_mask_u8<4, 1, rgb_to_gray_mask_u8<2, 1, 0> > alpha_mask_abgr32gray; //----alpha_mask_abgr32gray //==========================================================amask_no_clip_u8 template class amask_no_clip_u8 { public: typedef int8u cover_type; typedef amask_no_clip_u8 self_type; enum { cover_shift = 8, cover_none = 0, cover_full = 255 }; amask_no_clip_u8() : m_rbuf(0) {} amask_no_clip_u8(rendering_buffer& rbuf) : m_rbuf(&rbuf) {} void attach(rendering_buffer& rbuf) { m_rbuf = &rbuf; } MaskF& mask_function() { return m_mask_function; } const MaskF& mask_function() const { return m_mask_function; } //-------------------------------------------------------------------- cover_type pixel(int x, int y) const { return (cover_type)m_mask_function.calculate( m_rbuf->row(y) + x * Step + Offset); } //-------------------------------------------------------------------- cover_type combine_pixel(int x, int y, cover_type val) const { return (cover_type)((val * m_mask_function.calculate( m_rbuf->row(y) + x * Step + Offset)) >> cover_shift); } //-------------------------------------------------------------------- void fill_hspan(int x, int y, cover_type* dst, int num_pix) const { const int8u* mask = m_rbuf->row(y) + x * Step + Offset; do { *dst++ = (cover_type)m_mask_function.calculate(mask); mask += Step; } while(--num_pix); } //-------------------------------------------------------------------- void combine_hspan(int x, int y, cover_type* dst, int num_pix) const { const int8u* mask = m_rbuf->row(y) + x * Step + Offset; do { *dst = (cover_type)(((*dst) * m_mask_function.calculate(mask)) >> cover_shift); ++dst; mask += Step; } while(--num_pix); } //-------------------------------------------------------------------- void fill_vspan(int x, int y, cover_type* dst, int num_pix) const { const int8u* mask = m_rbuf->row(y) + x * Step + Offset; do { *dst++ = (cover_type)m_mask_function.calculate(mask); mask += m_rbuf->stride(); } while(--num_pix); } //-------------------------------------------------------------------- void combine_vspan(int x, int y, cover_type* dst, int num_pix) const { const int8u* mask = m_rbuf->row(y) + x * Step + Offset; do { *dst = (cover_type)(((*dst) * m_mask_function.calculate(mask)) >> cover_shift); ++dst; mask += m_rbuf->stride(); } while(--num_pix); } private: amask_no_clip_u8(const self_type&); const self_type& operator = (const self_type&); rendering_buffer* m_rbuf; MaskF m_mask_function; }; typedef amask_no_clip_u8<1, 0> amask_no_clip_gray8; //----amask_no_clip_gray8 typedef amask_no_clip_u8<3, 0> amask_no_clip_rgb24r; //----amask_no_clip_rgb24r typedef amask_no_clip_u8<3, 1> amask_no_clip_rgb24g; //----amask_no_clip_rgb24g typedef amask_no_clip_u8<3, 2> amask_no_clip_rgb24b; //----amask_no_clip_rgb24b typedef amask_no_clip_u8<3, 2> amask_no_clip_bgr24r; //----amask_no_clip_bgr24r typedef amask_no_clip_u8<3, 1> amask_no_clip_bgr24g; //----amask_no_clip_bgr24g typedef amask_no_clip_u8<3, 0> amask_no_clip_bgr24b; //----amask_no_clip_bgr24b typedef amask_no_clip_u8<4, 0> amask_no_clip_rgba32r; //----amask_no_clip_rgba32r typedef amask_no_clip_u8<4, 1> amask_no_clip_rgba32g; //----amask_no_clip_rgba32g typedef amask_no_clip_u8<4, 2> amask_no_clip_rgba32b; //----amask_no_clip_rgba32b typedef amask_no_clip_u8<4, 3> amask_no_clip_rgba32a; //----amask_no_clip_rgba32a typedef amask_no_clip_u8<4, 1> amask_no_clip_argb32r; //----amask_no_clip_argb32r typedef amask_no_clip_u8<4, 2> amask_no_clip_argb32g; //----amask_no_clip_argb32g typedef amask_no_clip_u8<4, 3> amask_no_clip_argb32b; //----amask_no_clip_argb32b typedef amask_no_clip_u8<4, 0> amask_no_clip_argb32a; //----amask_no_clip_argb32a typedef amask_no_clip_u8<4, 2> amask_no_clip_bgra32r; //----amask_no_clip_bgra32r typedef amask_no_clip_u8<4, 1> amask_no_clip_bgra32g; //----amask_no_clip_bgra32g typedef amask_no_clip_u8<4, 0> amask_no_clip_bgra32b; //----amask_no_clip_bgra32b typedef amask_no_clip_u8<4, 3> amask_no_clip_bgra32a; //----amask_no_clip_bgra32a typedef amask_no_clip_u8<4, 3> amask_no_clip_abgr32r; //----amask_no_clip_abgr32r typedef amask_no_clip_u8<4, 2> amask_no_clip_abgr32g; //----amask_no_clip_abgr32g typedef amask_no_clip_u8<4, 1> amask_no_clip_abgr32b; //----amask_no_clip_abgr32b typedef amask_no_clip_u8<4, 0> amask_no_clip_abgr32a; //----amask_no_clip_abgr32a typedef amask_no_clip_u8<3, 0, rgb_to_gray_mask_u8<0, 1, 2> > amask_no_clip_rgb24gray; //----amask_no_clip_rgb24gray typedef amask_no_clip_u8<3, 0, rgb_to_gray_mask_u8<2, 1, 0> > amask_no_clip_bgr24gray; //----amask_no_clip_bgr24gray typedef amask_no_clip_u8<4, 0, rgb_to_gray_mask_u8<0, 1, 2> > amask_no_clip_rgba32gray; //----amask_no_clip_rgba32gray typedef amask_no_clip_u8<4, 1, rgb_to_gray_mask_u8<0, 1, 2> > amask_no_clip_argb32gray; //----amask_no_clip_argb32gray typedef amask_no_clip_u8<4, 0, rgb_to_gray_mask_u8<2, 1, 0> > amask_no_clip_bgra32gray; //----amask_no_clip_bgra32gray typedef amask_no_clip_u8<4, 1, rgb_to_gray_mask_u8<2, 1, 0> > amask_no_clip_abgr32gray; //----amask_no_clip_abgr32gray } #endif aggdraw-1.3.14/agg2/include/agg_arc.h000066400000000000000000000037621417726601400172330ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Arc vertex generator // //---------------------------------------------------------------------------- #ifndef AGG_ARC_INCLUDED #define AGG_ARC_INCLUDED #include #include "agg_basics.h" namespace agg { //=====================================================================arc // // See Implementation agg_arc.cpp // class arc { public: arc() : m_scale(1.0), m_initialized(false) {} arc(double x, double y, double rx, double ry, double a1, double a2, bool ccw=true); void init(double x, double y, double rx, double ry, double a1, double a2, bool ccw=true); void approximation_scale(double s); double approximation_scale() const { return m_scale; } void rewind(unsigned); unsigned vertex(double* x, double* y); private: void normalize(double a1, double a2, bool ccw); double m_x; double m_y; double m_rx; double m_ry; double m_angle; double m_start; double m_end; double m_scale; double m_da; bool m_ccw; bool m_initialized; unsigned m_path_cmd; }; } #endif aggdraw-1.3.14/agg2/include/agg_array.h000066400000000000000000000503141417726601400175770ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_ARRAY_INCLUDED #define AGG_ARRAY_INCLUDED #include #include "agg_basics.h" namespace agg { //---------------------------------------------------------------pod_array // A simple class template to store Plain Old Data, a vector // of a fixed size. The data is continous in memory //------------------------------------------------------------------------ template class pod_array { public: typedef T value_type; ~pod_array() { delete [] m_array; } pod_array() : m_size(0), m_capacity(0), m_array(0) {} pod_array(unsigned cap, unsigned extra_tail=0); // Copying pod_array(const pod_array&); const pod_array& operator = (const pod_array&); unsigned capacity() const { return m_capacity; } void capacity(unsigned cap, unsigned extra_tail=0); void resize(unsigned new_size); void add(const T& v) { m_array[m_size++] = v; } void inc_size(unsigned size) { m_size += size; } unsigned size() const { return m_size; } const T& operator [] (unsigned idx) const { return m_array[idx]; } T& operator [] (unsigned idx) { return m_array[idx]; } void remove_all() { m_size = 0; } void cut_at(unsigned num) { if(num < m_size) m_size = num; } private: unsigned m_size; unsigned m_capacity; T* m_array; }; //------------------------------------------------------------------------ template void pod_array::capacity(unsigned cap, unsigned extra_tail) { m_size = 0; if(cap > m_capacity) { delete [] m_array; m_capacity = cap + extra_tail; m_array = m_capacity ? new T [m_capacity] : 0; } } //------------------------------------------------------------------------ template void pod_array::resize(unsigned new_size) { if(new_size > m_size) { if(new_size > m_capacity) { T* data = new T[new_size]; memcpy(data, m_array, m_size * sizeof(T)); delete [] m_array; m_array = data; } } else { m_size = new_size; } } //------------------------------------------------------------------------ template pod_array::pod_array(unsigned cap, unsigned extra_tail) : m_size(0), m_capacity(0), m_array(0) { capacity(cap, extra_tail); } //------------------------------------------------------------------------ template pod_array::pod_array(const pod_array& v) : m_size(v.m_size), m_capacity(v.m_capacity), m_array(v.m_capacity ? new T [v.m_capacity] : 0) { memcpy(m_array, v.m_array, sizeof(T) * v.m_size); } //------------------------------------------------------------------------ template const pod_array& pod_array::operator = (const pod_array&v) { capacity(v.m_capacity); if(v.m_size) memcpy(m_array, v.m_array, sizeof(T) * v.m_size); return *this; } //------------------------------------------------------------------------ template class pod_array_adaptor { public: typedef T value_type; pod_array_adaptor(T* array, unsigned size) : m_array(array), m_size(size) {} unsigned size() const { return m_size; } const T& operator [] (unsigned idx) const { return m_array[idx]; } T& operator [] (unsigned idx) { return m_array[idx]; } private: T* m_array; unsigned m_size; }; //---------------------------------------------------------------pod_deque // A simple class template to store Plain Old Data, similar to std::deque // It doesn't reallocate memory but instead, uses blocks of data of size // of (1 << S), that is, power of two. The data is NOT continuous in memory, // so the only valid access method is operator [] or curr(), prev(), next() // // There reallocs occure only when the pool of pointers to blocks needs // to be extended (it happens very rear). You can control the value // of increment to reallocate the pointer buffer. See the second constructor. // By default, the incremeent value equals (1 << S), i.e., the block size. //------------------------------------------------------------------------ template class pod_deque { enum { block_shift = S, block_size = 1 << block_shift, block_mask = block_size - 1 }; public: typedef T value_type; ~pod_deque(); pod_deque(); pod_deque(unsigned block_ptr_inc); // Copying pod_deque(const pod_deque& v); const pod_deque& operator = (const pod_deque& v); void remove_all() { m_size = 0; } void free_all() { free_tail(0); } void free_tail(unsigned size); void add(const T& val); void modify_last(const T& val); void remove_last(); int allocate_continuous_block(unsigned num_elements); void cut_at(unsigned size) { if(size < m_size) m_size = size; } unsigned size() const { return m_size; } const T& operator [] (unsigned idx) const { return m_blocks[idx >> block_shift][idx & block_mask]; } T& operator [] (unsigned idx) { return m_blocks[idx >> block_shift][idx & block_mask]; } const T& curr(unsigned idx) const { return (*this)[idx]; } T& curr(unsigned idx) { return (*this)[idx]; } const T& prev(unsigned idx) const { return (*this)[(idx + m_size - 1) % m_size]; } T& prev(unsigned idx) { return (*this)[(idx + m_size - 1) % m_size]; } const T& next(unsigned idx) const { return (*this)[(idx + 1) % m_size]; } T& next(unsigned idx) { return (*this)[(idx + 1) % m_size]; } const T& last() const { return (*this)[m_size - 1]; } T& last() { return (*this)[m_size - 1]; } unsigned byte_size() const; void serialize(int8u* ptr) const; private: void allocate_block(unsigned nb); T* data_ptr(); unsigned m_size; unsigned m_num_blocks; unsigned m_max_blocks; T** m_blocks; unsigned m_block_ptr_inc; }; //------------------------------------------------------------------------ template pod_deque::~pod_deque() { if(m_num_blocks) { T** blk = m_blocks + m_num_blocks - 1; while(m_num_blocks--) { delete [] *blk; --blk; } delete [] m_blocks; } } //------------------------------------------------------------------------ template void pod_deque::free_tail(unsigned size) { if(size < m_size) { unsigned nb = (size + block_mask) >> block_shift; while(m_num_blocks > nb) { delete [] m_blocks[--m_num_blocks]; } m_size = size; } } //------------------------------------------------------------------------ template pod_deque::pod_deque() : m_size(0), m_num_blocks(0), m_max_blocks(0), m_blocks(0), m_block_ptr_inc(block_size) { } //------------------------------------------------------------------------ template pod_deque::pod_deque(unsigned block_ptr_inc) : m_size(0), m_num_blocks(0), m_max_blocks(0), m_blocks(0), m_block_ptr_inc(block_ptr_inc) { } //------------------------------------------------------------------------ template pod_deque::pod_deque(const pod_deque& v) : m_size(v.m_size), m_num_blocks(v.m_num_blocks), m_max_blocks(v.m_max_blocks), m_blocks(v.m_max_blocks ? new T* [v.m_max_blocks] : 0), m_block_ptr_inc(v.m_block_ptr_inc) { unsigned i; for(i = 0; i < v.m_num_blocks; ++i) { m_blocks[i] = new T [block_size]; memcpy(m_blocks[i], v.m_blocks[i], block_size * sizeof(T)); } } //------------------------------------------------------------------------ template const pod_deque& pod_deque::operator = (const pod_deque& v) { unsigned i; for(i = m_num_blocks; i < v.m_num_blocks; ++i) { allocate_block(i); } for(i = 0; i < v.m_num_blocks; ++i) { memcpy(m_blocks[i], v.m_blocks[i], block_size * sizeof(T)); } m_size = v.m_size; return *this; } //------------------------------------------------------------------------ template void pod_deque::allocate_block(unsigned nb) { if(nb >= m_max_blocks) { T** new_blocks = new T* [m_max_blocks + m_block_ptr_inc]; if(m_blocks) { memcpy(new_blocks, m_blocks, m_num_blocks * sizeof(T*)); delete [] m_blocks; } m_blocks = new_blocks; m_max_blocks += m_block_ptr_inc; } m_blocks[nb] = new T [block_size]; m_num_blocks++; } //------------------------------------------------------------------------ template inline T* pod_deque::data_ptr() { unsigned nb = m_size >> block_shift; if(nb >= m_num_blocks) { allocate_block(nb); } return m_blocks[nb] + (m_size & block_mask); } //------------------------------------------------------------------------ template inline void pod_deque::add(const T& val) { *data_ptr() = val; ++m_size; } //------------------------------------------------------------------------ template inline void pod_deque::remove_last() { if(m_size) --m_size; } //------------------------------------------------------------------------ template void pod_deque::modify_last(const T& val) { remove_last(); add(val); } //------------------------------------------------------------------------ template int pod_deque::allocate_continuous_block(unsigned num_elements) { if(num_elements < block_size) { data_ptr(); // Allocate initial block if necessary unsigned rest = block_size - (m_size & block_mask); unsigned index; if(num_elements <= rest) { // The rest of the block is good, we can use it //----------------- index = m_size; m_size += num_elements; return index; } // New block //--------------- m_size += rest; data_ptr(); index = m_size; m_size += num_elements; return index; } return -1; // Impossible to allocate } //------------------------------------------------------------------------ template unsigned pod_deque::byte_size() const { return m_size * sizeof(T); } //------------------------------------------------------------------------ template void pod_deque::serialize(int8u* ptr) const { unsigned i; for(i = 0; i < m_size; i++) { memcpy(ptr, &(*this)[i], sizeof(T)); ptr += sizeof(T); } } //-----------------------------------------------------------pod_allocator // Allocator for arbitrary POD data. Most usable in different cache // systems for efficient memory allocations. // Memory is allocated with blocks of fixed size ("block_size" in // the constructor). If required size exceeds the block size the allocator // creates a new block of the required size. However, the most efficient // use is when the average reqired size is much less than the block size. //------------------------------------------------------------------------ class pod_allocator { public: void remove_all() { if(m_num_blocks) { int8u** blk = m_blocks + m_num_blocks - 1; while(m_num_blocks--) { delete [] *blk; --blk; } delete [] m_blocks; } m_num_blocks = 0; m_max_blocks = 0; m_blocks = 0; m_buf_ptr = 0; m_rest = 0; } ~pod_allocator() { remove_all(); } pod_allocator(unsigned block_size, unsigned block_ptr_inc=256-8) : m_block_size(block_size), m_block_ptr_inc(block_ptr_inc), m_num_blocks(0), m_max_blocks(0), m_blocks(0), m_buf_ptr(0), m_rest(0) { } int8u* allocate(unsigned size, unsigned alignment=1) { if(size == 0) return 0; if(size <= m_rest) { int8u* ptr = m_buf_ptr; if(alignment > 1) { unsigned align = (alignment - (unsigned long)(ptr) % alignment) % alignment; size += align; ptr += align; if(size <= m_rest) { m_rest -= size; m_buf_ptr += size; return ptr; } allocate_block(size); return allocate(size - align, alignment); } m_rest -= size; m_buf_ptr += size; return ptr; } allocate_block(size + alignment - 1); return allocate(size, alignment); } private: void allocate_block(unsigned size) { if(size < m_block_size) size = m_block_size; if(m_num_blocks >= m_max_blocks) { int8u** new_blocks = new int8u* [m_max_blocks + m_block_ptr_inc]; if(m_blocks) { memcpy(new_blocks, m_blocks, m_num_blocks * sizeof(int8u*)); delete [] m_blocks; } m_blocks = new_blocks; m_max_blocks += m_block_ptr_inc; } m_blocks[m_num_blocks] = m_buf_ptr = new int8u [size]; m_num_blocks++; m_rest = size; } unsigned m_block_size; unsigned m_block_ptr_inc; unsigned m_num_blocks; unsigned m_max_blocks; int8u** m_blocks; int8u* m_buf_ptr; unsigned m_rest; }; //------------------------------------------------------------------------ enum { quick_sort_threshold = 9 }; //-----------------------------------------------------------swap_elements template inline void swap_elements(T& a, T& b) { T temp = a; a = b; b = temp; } //--------------------------------------------------------------quick_sort template void quick_sort(Array& arr, Less less) { if(arr.size() < 2) return; typename Array::value_type* e1; typename Array::value_type* e2; int stack[80]; int* top = stack; int limit = arr.size(); int base = 0; for(;;) { int len = limit - base; int i; int j; int pivot; if(len > quick_sort_threshold) { // we use base + len/2 as the pivot pivot = base + len / 2; swap_elements(arr[base], arr[pivot]); i = base + 1; j = limit - 1; // now ensure that *i <= *base <= *j e1 = &(arr[j]); e2 = &(arr[i]); if(less(*e1, *e2)) swap_elements(*e1, *e2); e1 = &(arr[base]); e2 = &(arr[i]); if(less(*e1, *e2)) swap_elements(*e1, *e2); e1 = &(arr[j]); e2 = &(arr[base]); if(less(*e1, *e2)) swap_elements(*e1, *e2); for(;;) { do i++; while( less(arr[i], arr[base]) ); do j--; while( less(arr[base], arr[j]) ); if( i > j ) { break; } swap_elements(arr[i], arr[j]); } swap_elements(arr[base], arr[j]); // now, push the largest sub-array if(j - base > limit - i) { top[0] = base; top[1] = j; base = i; } else { top[0] = i; top[1] = limit; limit = j; } top += 2; } else { // the sub-array is small, perform insertion sort j = base; i = j + 1; for(; i < limit; j = i, i++) { for(; less(*(e1 = &(arr[j + 1])), *(e2 = &(arr[j]))); j--) { swap_elements(*e1, *e2); if(j == base) { break; } } } if(top > stack) { top -= 2; base = top[0]; limit = top[1]; } else { break; } } } } //------------------------------------------------------remove_duplicates // Remove duplicates from a sorted array. It doesn't cut the the // tail of the array, it just returns the number of remaining elements. //----------------------------------------------------------------------- template unsigned remove_duplicates(Array& arr, Equal equal) { if(arr.size() < 2) return arr.size(); unsigned i, j; for(i = 1, j = 1; i < arr.size(); i++) { typename Array::value_type& e = arr[i]; if(!equal(e, arr[i - 1])) { arr[j++] = e; } } return j; } } #endif aggdraw-1.3.14/agg2/include/agg_arrowhead.h000066400000000000000000000044141417726601400204350ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Simple arrowhead/arrowtail generator // //---------------------------------------------------------------------------- #ifndef AGG_ARROWHEAD_INCLUDED #define AGG_ARROWHEAD_INCLUDED #include "agg_basics.h" namespace agg { //===============================================================arrowhead // // See implementation agg_arrowhead.cpp // class arrowhead { public: arrowhead(); void head(double d1, double d2, double d3, double d4) { m_head_d1 = d1; m_head_d2 = d2; m_head_d3 = d3; m_head_d4 = d4; m_head_flag = true; } void head() { m_head_flag = true; } void no_head() { m_head_flag = false; } void tail(double d1, double d2, double d3, double d4) { m_tail_d1 = d1; m_tail_d2 = d2; m_tail_d3 = d3; m_tail_d4 = d4; m_tail_flag = true; } void tail() { m_tail_flag = true; } void no_tail() { m_tail_flag = false; } void rewind(unsigned id); unsigned vertex(double* x, double* y); private: double m_head_d1; double m_head_d2; double m_head_d3; double m_head_d4; double m_tail_d1; double m_tail_d2; double m_tail_d3; double m_tail_d4; bool m_head_flag; bool m_tail_flag; double m_coord[16]; unsigned m_cmd[8]; unsigned m_curr_id; unsigned m_curr_coord; }; } #endif aggdraw-1.3.14/agg2/include/agg_basics.h000066400000000000000000000213571417726601400177320ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_BASICS_INCLUDED #define AGG_BASICS_INCLUDED namespace agg { //------------------------------------------------------------------------- typedef signed char int8; //----int8 typedef unsigned char int8u; //----int8u typedef signed short int16; //----int16 typedef unsigned short int16u; //----int16u typedef signed int int32; //----int32 typedef unsigned int int32u; //----int32u //------------------------------------------------------------------------- typedef unsigned char cover_type; //----cover_type enum { cover_shift = 8, //----cover_shift cover_size = 1 << cover_shift, //----cover_size cover_mask = cover_size - 1, //----cover_mask cover_none = 0, //----cover_none cover_full = cover_mask //----cover_full }; //-----------------------------------------------------------------------pi const double pi = 3.14159265358979323846; //------------------------------------------------------------------deg2rad inline double deg2rad(double deg) { return deg * pi / 180.0; } //------------------------------------------------------------------rad2deg inline double rad2deg(double rad) { return rad * 180.0 / pi; } //----------------------------------------------------------------rect_base template struct rect_base { typedef rect_base self_type; T x1; T y1; T x2; T y2; rect_base() {} rect_base(T x1_, T y1_, T x2_, T y2_) : x1(x1_), y1(y1_), x2(x2_), y2(y2_) {} const self_type& normalize() { T t; if(x1 > x2) { t = x1; x1 = x2; x2 = t; } if(y1 > y2) { t = y1; y1 = y2; y2 = t; } return *this; } bool clip(const self_type& r) { if(x2 > r.x2) x2 = r.x2; if(y2 > r.y2) y2 = r.y2; if(x1 < r.x1) x1 = r.x1; if(y1 < r.y1) y1 = r.y1; return x1 <= x2 && y1 <= y2; } bool is_valid() const { return x1 <= x2 && y1 <= y2; } }; //-----------------------------------------------------intersect_rectangles template inline Rect intersect_rectangles(const Rect& r1, const Rect& r2) { Rect r = r1; // First process x2,y2 because the other order // results in Internal Compiler Error under // Microsoft Visual C++ .NET 2003 69462-335-0000007-18038 in // case of "Maximize Speed" optimization option. //----------------- if(r.x2 > r2.x2) r.x2 = r2.x2; if(r.y2 > r2.y2) r.y2 = r2.y2; if(r.x1 < r2.x1) r.x1 = r2.x1; if(r.y1 < r2.y1) r.y1 = r2.y1; return r; } //---------------------------------------------------------unite_rectangles template inline Rect unite_rectangles(const Rect& r1, const Rect& r2) { Rect r = r1; if(r.x2 < r2.x2) r.x2 = r2.x2; if(r.y2 < r2.y2) r.y2 = r2.y2; if(r.x1 > r2.x1) r.x1 = r2.x1; if(r.y1 > r2.y1) r.y1 = r2.y1; return r; } typedef rect_base rect; //----rect typedef rect_base rect_d; //----rect_d //---------------------------------------------------------path_commands_e enum path_commands_e { path_cmd_stop = 0, //----path_cmd_stop path_cmd_move_to = 1, //----path_cmd_move_to path_cmd_line_to = 2, //----path_cmd_line_to path_cmd_curve3 = 3, //----path_cmd_curve3 path_cmd_curve4 = 4, //----path_cmd_curve4 path_cmd_end_poly = 6, //----path_cmd_end_poly path_cmd_mask = 0x0F //----path_cmd_mask }; //------------------------------------------------------------path_flags_e enum path_flags_e { path_flags_none = 0, //----path_flags_none path_flags_ccw = 0x10, //----path_flags_ccw path_flags_cw = 0x20, //----path_flags_cw path_flags_close = 0x40, //----path_flags_close path_flags_mask = 0xF0 //----path_flags_mask }; //---------------------------------------------------------------is_vertex inline bool is_vertex(unsigned c) { return c >= path_cmd_move_to && c < path_cmd_end_poly; } //-----------------------------------------------------------------is_stop inline bool is_stop(unsigned c) { return c == path_cmd_stop; } //--------------------------------------------------------------is_move_to inline bool is_move_to(unsigned c) { return c == path_cmd_move_to; } //--------------------------------------------------------------is_line_to inline bool is_line_to(unsigned c) { return c == path_cmd_line_to; } //----------------------------------------------------------------is_curve inline bool is_curve(unsigned c) { return c == path_cmd_curve3 || c == path_cmd_curve4; } //---------------------------------------------------------------is_curve3 inline bool is_curve3(unsigned c) { return c == path_cmd_curve3; } //---------------------------------------------------------------is_curve4 inline bool is_curve4(unsigned c) { return c == path_cmd_curve4; } //-------------------------------------------------------------is_end_poly inline bool is_end_poly(unsigned c) { return (c & path_cmd_mask) == path_cmd_end_poly; } //----------------------------------------------------------------is_close inline bool is_close(unsigned c) { return (c & ~(path_flags_cw | path_flags_ccw)) == (path_cmd_end_poly | path_flags_close); } //------------------------------------------------------------is_next_poly inline bool is_next_poly(unsigned c) { return is_stop(c) || is_move_to(c) || is_end_poly(c); } //-------------------------------------------------------------------is_cw inline bool is_cw(unsigned c) { return (c & path_flags_cw) != 0; } //------------------------------------------------------------------is_ccw inline bool is_ccw(unsigned c) { return (c & path_flags_ccw) != 0; } //-------------------------------------------------------------is_oriented inline bool is_oriented(unsigned c) { return (c & (path_flags_cw | path_flags_ccw)) != 0; } //---------------------------------------------------------------is_closed inline bool is_closed(unsigned c) { return (c & path_flags_close) != 0; } //----------------------------------------------------------get_close_flag inline unsigned get_close_flag(unsigned c) { return c & path_flags_close; } //-------------------------------------------------------clear_orientation inline unsigned clear_orientation(unsigned c) { return c & ~(path_flags_cw | path_flags_ccw); } //---------------------------------------------------------get_orientation inline unsigned get_orientation(unsigned c) { return c & (path_flags_cw | path_flags_ccw); } //---------------------------------------------------------set_orientation inline unsigned set_orientation(unsigned c, unsigned o) { return clear_orientation(c) | o; } //--------------------------------------------------------------point_type struct point_type { double x, y; point_type() {} point_type(double x_, double y_) : x(x_), y(y_) {} }; //-------------------------------------------------------------vertex_type struct vertex_type { double x, y; unsigned cmd; vertex_type() {} vertex_type(double x_, double y_, unsigned cmd_) : x(x_), y(y_), cmd(cmd_) {} }; } #endif aggdraw-1.3.14/agg2/include/agg_bezier_arc.h000066400000000000000000000126671417726601400205770ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Arc generator. Produces at most 4 consecutive cubic bezier curves, i.e., // 4, 7, 10, or 13 vertices. // //---------------------------------------------------------------------------- #ifndef AGG_BEZIER_ARC_INCLUDED #define AGG_BEZIER_ARC_INCLUDED #include "agg_conv_transform.h" namespace agg { //----------------------------------------------------------------------- void arc_to_bezier(double cx, double cy, double rx, double ry, double start_angle, double sweep_angle, double* curve); //==============================================================bezier_arc // // See implemantaion agg_bezier_arc.cpp // class bezier_arc { public: bezier_arc() : m_vertex(26) {} bezier_arc(double x, double y, double rx, double ry, double start_angle, double sweep_angle) { init(x, y, rx, ry, start_angle, sweep_angle); } void init(double x, double y, double rx, double ry, double start_angle, double sweep_angle); //-------------------------------------------------------------------- void rewind(unsigned) { m_vertex = 0; } //-------------------------------------------------------------------- unsigned vertex(double* x, double* y) { if(m_vertex >= m_num_vertices) return path_cmd_stop; *x = m_vertices[m_vertex]; *y = m_vertices[m_vertex + 1]; m_vertex += 2; return (m_vertex == 2) ? path_cmd_move_to : path_cmd_curve4; } // Supplemantary functions. num_vertices() actually returns doubled // number of vertices. That is, for 1 vertex it returns 2. //-------------------------------------------------------------------- unsigned num_vertices() const { return m_num_vertices; } const double* vertices() const { return m_vertices; } double* vertices() { return m_vertices; } private: unsigned m_vertex; unsigned m_num_vertices; double m_vertices[26]; }; //==========================================================bezier_arc_svg // Compute an SVG-style bezier arc. // // Computes an elliptical arc from (x1, y1) to (x2, y2). The size and // orientation of the ellipse are defined by two radii (rx, ry) // and an x-axis-rotation, which indicates how the ellipse as a whole // is rotated relative to the current coordinate system. The center // (cx, cy) of the ellipse is calculated automatically to satisfy the // constraints imposed by the other parameters. // large-arc-flag and sweep-flag contribute to the automatic calculations // and help determine how the arc is drawn. class bezier_arc_svg { public: //-------------------------------------------------------------------- bezier_arc_svg() : m_arc(), m_radii_ok(false) {} bezier_arc_svg(double x1, double y1, double rx, double ry, double angle, bool large_arc_flag, bool sweep_flag, double x2, double y2) : m_arc(), m_radii_ok(false) { init(x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2); } //-------------------------------------------------------------------- void init(double x1, double y1, double rx, double ry, double angle, bool large_arc_flag, bool sweep_flag, double x2, double y2); //-------------------------------------------------------------------- bool radii_ok() const { return m_radii_ok; } //-------------------------------------------------------------------- void rewind(unsigned) { m_arc.rewind(0); } //-------------------------------------------------------------------- unsigned vertex(double* x, double* y) { return m_arc.vertex(x, y); } // Supplemantary functions. num_vertices() actually returns doubled // number of vertices. That is, for 1 vertex it returns 2. //-------------------------------------------------------------------- unsigned num_vertices() const { return m_arc.num_vertices(); } const double* vertices() const { return m_arc.vertices(); } double* vertices() { return m_arc.vertices(); } private: bezier_arc m_arc; bool m_radii_ok; }; } #endif aggdraw-1.3.14/agg2/include/agg_bitset_iterator.h000066400000000000000000000026141417726601400216640ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_BITSET_ITERATOR_INCLUDED #define AGG_BITSET_ITERATOR_INCLUDED #include "agg_basics.h" namespace agg { class bitset_iterator { public: bitset_iterator(const int8u* bits, unsigned offset = 0) : m_bits(bits + (offset >> 3)), m_mask(0x80 >> (offset & 7)) {} void operator ++ () { m_mask >>= 1; if(m_mask == 0) { ++m_bits; m_mask = 0x80; } } unsigned bit() const { return (*m_bits) & m_mask; } private: const int8u* m_bits; int8u m_mask; }; } #endif aggdraw-1.3.14/agg2/include/agg_bounding_rect.h000066400000000000000000000064701417726601400213070ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // bounding_rect function template // //---------------------------------------------------------------------------- #ifndef AGG_BOUNDING_RECT_INCLUDED #define AGG_BOUNDING_RECT_INCLUDED #include "agg_basics.h" namespace agg { //-----------------------------------------------------------bounding_rect template bool bounding_rect(VertexSource& vs, GetId& gi, unsigned start, unsigned num, CoordT* x1, CoordT* y1, CoordT* x2, CoordT* y2) { unsigned i; double x; double y; bool first = true; for(i = 0; i < num; i++) { vs.rewind(gi[start + i]); unsigned cmd; while(!is_stop(cmd = vs.vertex(&x, &y))) { if(is_vertex(cmd)) { if(first) { *x1 = CoordT(x); *y1 = CoordT(y); *x2 = CoordT(x); *y2 = CoordT(y); first = false; } else { if(CoordT(x) < *x1) *x1 = CoordT(x); if(CoordT(y) < *y1) *y1 = CoordT(y); if(CoordT(x) > *x2) *x2 = CoordT(x); if(CoordT(y) > *y2) *y2 = CoordT(y); } } } } return *x1 <= *x2 && *y1 <= *y2; } //-----------------------------------------------------bounding_rect_single template bool bounding_rect_single(VertexSource& vs, unsigned path_id, CoordT* x1, CoordT* y1, CoordT* x2, CoordT* y2) { double x; double y; bool first = true; vs.rewind(path_id); unsigned cmd; while(!is_stop(cmd = vs.vertex(&x, &y))) { if(is_vertex(cmd)) { if(first) { *x1 = CoordT(x); *y1 = CoordT(y); *x2 = CoordT(x); *y2 = CoordT(y); first = false; } else { if(CoordT(x) < *x1) *x1 = CoordT(x); if(CoordT(y) < *y1) *y1 = CoordT(y); if(CoordT(x) > *x2) *x2 = CoordT(x); if(CoordT(y) > *y2) *y2 = CoordT(y); } } } return *x1 <= *x2 && *y1 <= *y2; } } #endif aggdraw-1.3.14/agg2/include/agg_bspline.h000066400000000000000000000050551417726601400201170ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // class bspline // //---------------------------------------------------------------------------- #ifndef AGG_BSPLINE_INCLUDED #define AGG_BSPLINE_INCLUDED #include "agg_basics.h" namespace agg { //----------------------------------------------------------------bspline // A very simple class of Bi-cubic Spline interpolation. // First call init(num, x[], y[]) where num - number of source points, // x, y - arrays of X and Y values respectively. Here Y must be a function // of X. It means that all the X-coordinates must be arranged in the ascending // order. // Then call get(x) that calculates a value Y for the respective X. // The class supports extrapolation, i.e. you can call get(x) where x is // outside the given with init() X-range. Extrapolation is a simple linear // function. // // See Implementation agg_bspline.cpp //------------------------------------------------------------------------ class bspline { public: ~bspline(); bspline(); bspline(int num); bspline(int num, const double* x, const double* y); void init(int num); void add_point(double x, double y); void prepare(); void init(int num, const double* x, const double* y); double get(double x) const; double get_stateful(double x) const; private: bspline(const bspline&); const bspline& operator = (const bspline&); static void bsearch(int n, const double *x, double x0, int *i); double extrapolation_left(double x) const; double extrapolation_right(double x) const; double interpolation(double x, int i) const; int m_max; int m_num; double* m_x; double* m_y; double* m_am; mutable int m_last_idx; }; } #endif aggdraw-1.3.14/agg2/include/agg_clip_liang_barsky.h000066400000000000000000000117461417726601400221430ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Liang-Barsky clipping // //---------------------------------------------------------------------------- #ifndef AGG_CLIP_LIANG_BARSKY_INCLUDED #define AGG_CLIP_LIANG_BARSKY_INCLUDED #include "agg_basics.h" namespace agg { //-------------------------------------------------------clip_liang_barsky template inline unsigned clip_liang_barsky(T x1, T y1, T x2, T y2, const rect_base& clip_box, T* x, T* y) { const double nearzero = 1e-30; double deltax = x2 - x1; double deltay = y2 - y1; double xin; double xout; double yin; double yout; double tinx; double tiny; double toutx; double touty; double tin1; double tin2; double tout1; unsigned np = 0; if(deltax == 0.0) { // bump off of the vertical deltax = (x1 > clip_box.x1) ? -nearzero : nearzero; } if(deltay == 0.0) { // bump off of the horizontal deltay = (y1 > clip_box.y1) ? -nearzero : nearzero; } if(deltax > 0.0) { // points to right xin = clip_box.x1; xout = clip_box.x2; } else { xin = clip_box.x2; xout = clip_box.x1; } if(deltay > 0.0) { // points up yin = clip_box.y1; yout = clip_box.y2; } else { yin = clip_box.y2; yout = clip_box.y1; } tinx = (xin - x1) / deltax; tiny = (yin - y1) / deltay; if (tinx < tiny) { // hits x first tin1 = tinx; tin2 = tiny; } else { // hits y first tin1 = tiny; tin2 = tinx; } if(tin1 <= 1.0) { if(0.0 < tin1) { *x++ = (T)xin; *y++ = (T)yin; ++np; } if(tin2 <= 1.0) { toutx = (xout - x1) / deltax; touty = (yout - y1) / deltay; tout1 = (toutx < touty) ? toutx : touty; if(tin2 > 0.0 || tout1 > 0.0) { if(tin2 <= tout1) { if(tin2 > 0.0) { if(tinx > tiny) { *x++ = (T)xin; *y++ = (T)(y1 + tinx * deltay); } else { *x++ = (T)(x1 + tiny * deltax); *y++ = (T)yin; } ++np; } if(tout1 < 1.0) { if(toutx < touty) { *x++ = (T)xout; *y++ = (T)(y1 + toutx * deltay); } else { *x++ = (T)(x1 + touty * deltax); *y++ = (T)yout; } } else { *x++ = x2; *y++ = y2; } ++np; } else { if(tinx > tiny) { *x++ = (T)xin; *y++ = (T)yout; } else { *x++ = (T)xout; *y++ = (T)yin; } ++np; } } } } return np; } } #endif aggdraw-1.3.14/agg2/include/agg_color_rgba.h000066400000000000000000000157621417726601400206020ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // color type rgba // //---------------------------------------------------------------------------- #ifndef AGG_COLOR_RGBA_INCLUDED #define AGG_COLOR_RGBA_INCLUDED #include #include "agg_basics.h" namespace agg { //====================================================================rgba struct rgba { enum premul { pre }; double r; double g; double b; double a; //-------------------------------------------------------------------- rgba() {} //-------------------------------------------------------------------- rgba(double r_, double g_, double b_, double a_=1.0) : r(r_), g(g_), b(b_), a(a_) {} //-------------------------------------------------------------------- rgba(premul, double r_, double g_, double b_, double a_=1.0) : r(r_), g(g_), b(b_), a(a_) { premultiply(); } //-------------------------------------------------------------------- rgba(premul, const rgba& c) : r(c.r), g(c.g), b(c.b), a(c.a) { premultiply(); } //-------------------------------------------------------------------- rgba(const rgba& c, double a_) : r(c.r), g(c.g), b(c.b), a(a_) {} //-------------------------------------------------------------------- rgba(premul, const rgba& c, double a_) : r(c.r), g(c.g), b(c.b), a(a_) { premultiply(); } //-------------------------------------------------------------------- void clear() { r = g = b = a = 0; } //-------------------------------------------------------------------- const rgba& transparent() { a = 0.0; return *this; } //-------------------------------------------------------------------- const rgba& transparent(premul) { clear(); return *this; } //-------------------------------------------------------------------- const rgba& opacity(double a_) { if(a_ < 0.0) a_ = 0.0; if(a_ > 1.0) a_ = 1.0; a = a_; return *this; } //-------------------------------------------------------------------- const rgba& opacity(premul, double a_) { if(a_ < 0.0) a_ = 0.0; if(a_ > 1.0) a_ = 1.0; premultiply(a_); return *this; } //-------------------------------------------------------------------- double opacity() const { return a; } //-------------------------------------------------------------------- const rgba& premultiply() { r *= a; g *= a; b *= a; return *this; } //-------------------------------------------------------------------- const rgba& premultiply(double a_) { if(a == 0.0 || a_ == 0.0) { r = g = b = a = 0.0; return *this; } a_ /= a; r *= a_; g *= a_; b *= a_; a = a_; return *this; } //-------------------------------------------------------------------- const rgba& demultiply() { if(a == 0) { r = g = b = 0; return *this; } double a_ = 1.0 / a; r *= a_; g *= a_; b *= a_; return *this; } //-------------------------------------------------------------------- rgba gradient(rgba c, double k) const { rgba ret; ret.r = r + (c.r - r) * k; ret.g = g + (c.g - g) * k; ret.b = b + (c.b - b) * k; ret.a = a + (c.a - a) * k; return ret; } //-------------------------------------------------------------------- static rgba no_color() { return rgba(0,0,0,0); } //-------------------------------------------------------------------- static rgba from_wavelength(double wl, double gamma = 1.0); //-------------------------------------------------------------------- rgba(double wavelen, double gamma=1.0) { *this = from_wavelength(wavelen, gamma); } }; //------------------------------------------------------------------------ inline rgba rgba_pre(double r, double g, double b, double a=1.0) { return rgba(rgba::pre, r, g, b, a); } //-------------------------------------------------------------------- inline rgba rgba_pre(const rgba& c) { return rgba(rgba::pre, c); } //-------------------------------------------------------------------- inline rgba rgba_pre(const rgba& c, double a) { return rgba(rgba::pre, c, a); } //------------------------------------------------------------------------ inline rgba rgba::from_wavelength(double wl, double gamma) { rgba t(0.0, 0.0, 0.0); if(wl >= 380.0 && wl <= 440.0) { t.r = -1.0 * (wl - 440.0) / (440.0 - 380.0); t.b = 1.0; } else if(wl >= 440.0 && wl <= 490.0) { t.g = (wl - 440.0) / (490.0 - 440.0); t.b = 1.0; } else if(wl >= 490.0 && wl <= 510.0) { t.g = 1.0; t.b = -1.0 * (wl - 510.0) / (510.0 - 490.0); } else if(wl >= 510.0 && wl <= 580.0) { t.r = (wl - 510.0) / (580.0 - 510.0); t.g = 1.0; } else if(wl >= 580.0 && wl <= 645.0) { t.r = 1.0; t.g = -1.0 * (wl - 645.0) / (645.0 - 580.0); } else if(wl >= 645.0 && wl <= 780.0) { t.r = 1.0; } double s = 1.0; if(wl > 700.0) s = 0.3 + 0.7 * (780.0 - wl) / (780.0 - 700.0); else if(wl < 420.0) s = 0.3 + 0.7 * (wl - 380.0) / (420.0 - 380.0); t.r = pow(t.r * s, gamma); t.g = pow(t.g * s, gamma); t.b = pow(t.b * s, gamma); return t; } } #endif aggdraw-1.3.14/agg2/include/agg_color_rgba8.h000066400000000000000000000210531417726601400206600ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // color type rgba8 // //---------------------------------------------------------------------------- #ifndef AGG_COLOR_RGBA8_INCLUDED #define AGG_COLOR_RGBA8_INCLUDED #include "agg_basics.h" #include "agg_color_rgba.h" namespace agg { // Supported byte orders for RGB and RGBA pixel formats //======================================================================= struct order_rgb24 { enum { R=0, G=1, B=2, rgb24_tag }; }; //----order_rgb24 struct order_bgr24 { enum { B=0, G=1, R=2, rgb24_tag }; }; //----order_bgr24 struct order_rgba32 { enum { R=0, G=1, B=2, A=3, rgba32_tag }; }; //----order_rgba32 struct order_argb32 { enum { A=0, R=1, G=2, B=3, rgba32_tag }; }; //----order_argb32 struct order_abgr32 { enum { A=0, B=1, G=2, R=3, rgba32_tag }; }; //----order_abgr32 struct order_bgra32 { enum { B=0, G=1, R=2, A=3, rgba32_tag }; }; //----order_bgra32 //==================================================================rgba8 struct rgba8 { enum order { rgb, bgr }; enum premul { pre }; int8u r; int8u g; int8u b; int8u a; //-------------------------------------------------------------------- rgba8() {} //-------------------------------------------------------------------- rgba8(unsigned r_, unsigned g_, unsigned b_, unsigned a_=255) : r(int8u(r_)), g(int8u(g_)), b(int8u(b_)), a(int8u(a_)) {} //-------------------------------------------------------------------- rgba8(premul, unsigned r_, unsigned g_, unsigned b_, unsigned a_=255) : r(int8u(r_)), g(int8u(g_)), b(int8u(b_)), a(int8u(a_)) { premultiply(); } //-------------------------------------------------------------------- rgba8(const rgba& c) : r(int8u(c.r * 255.0 + 0.5)), g(int8u(c.g * 255.0 + 0.5)), b(int8u(c.b * 255.0 + 0.5)), a(int8u(c.a * 255.0 + 0.5)) {} //-------------------------------------------------------------------- rgba8(premul, const rgba8& c) : r(int8u(c.r)), g(int8u(c.g)), b(int8u(c.b)), a(int8u(c.a)) { premultiply(); } //-------------------------------------------------------------------- rgba8(const rgba8& c, unsigned a_) : r(int8u(c.r)), g(int8u(c.g)), b(int8u(c.b)), a(int8u(a_)) {} //-------------------------------------------------------------------- rgba8(premul, const rgba8& c, unsigned a_) : r(int8u(c.r)), g(int8u(c.g)), b(int8u(c.b)), a(int8u(a_)) { premultiply(); } //-------------------------------------------------------------------- rgba8(unsigned packed, order o) : r(int8u((o == rgb) ? ((packed >> 16) & 0xFF) : (packed & 0xFF))), g(int8u((packed >> 8) & 0xFF)), b(int8u((o == rgb) ? (packed & 0xFF) : ((packed >> 16) & 0xFF))), a(255) {} //-------------------------------------------------------------------- rgba8(premul, unsigned packed, order o) : r(int8u((o == rgb) ? ((packed >> 16) & 0xFF) : (packed & 0xFF))), g(int8u((packed >> 8) & 0xFF)), b(int8u((o == rgb) ? (packed & 0xFF) : ((packed >> 16) & 0xFF))), a(255) { premultiply(); } //-------------------------------------------------------------------- void clear() { r = g = b = a = 0; } //-------------------------------------------------------------------- const rgba8& transparent() { a = 0; return *this; } //-------------------------------------------------------------------- const rgba8& transparent(premul) { clear(); return *this; } //-------------------------------------------------------------------- const rgba8& opacity(double a_) { if(a_ < 0.0) a_ = 0.0; if(a_ > 1.0) a_ = 1.0; a = int8u(a_ * 255.0 + 0.5); return *this; } //-------------------------------------------------------------------- const rgba8& opacity(premul, double a_) { if(a_ < 0.0) a_ = 0.0; if(a_ > 1.0) a_ = 1.0; a = int8u(a_ * 255.0 + 0.5); premultiply(int8u(a_ * 255.0)); return *this; } //-------------------------------------------------------------------- double opacity() const { return double(a) / 255.0; } //-------------------------------------------------------------------- const rgba8& premultiply() { if(a == 255) return *this; if(a == 0) { r = g = b = 0; return *this; } r = (r * a) >> 8; g = (g * a) >> 8; b = (b * a) >> 8; return *this; } //-------------------------------------------------------------------- const rgba8& premultiply(unsigned a_) { if(a == 255 && a_ >= 255) return *this; if(a == 0 || a_ == 0) { r = g = b = a = 0; return *this; } unsigned r_ = (r * a_) / a; unsigned g_ = (g * a_) / a; unsigned b_ = (b * a_) / a; r = int8u((r_ > a_) ? a_ : r_); g = int8u((g_ > a_) ? a_ : g_); b = int8u((b_ > a_) ? a_ : b_); a = int8u(a_); return *this; } //-------------------------------------------------------------------- const rgba8& demultiply() { if(a == 255) return *this; if(a == 0) { r = g = b = 0; return *this; } unsigned r_ = (r * 255) / a; unsigned g_ = (g * 255) / a; unsigned b_ = (b * 255) / a; r = (r_ > 255) ? 255 : r_; g = (g_ > 255) ? 255 : g_; b = (b_ > 255) ? 255 : b_; return *this; } //-------------------------------------------------------------------- rgba8 gradient(rgba8 c, double k) const { rgba8 ret; int ik = int(k * 256); ret.r = int8u(int(r) + (((int(c.r) - int(r)) * ik) >> 8)); ret.g = int8u(int(g) + (((int(c.g) - int(g)) * ik) >> 8)); ret.b = int8u(int(b) + (((int(c.b) - int(b)) * ik) >> 8)); ret.a = int8u(int(a) + (((int(c.a) - int(a)) * ik) >> 8)); return ret; } //-------------------------------------------------------------------- static rgba8 no_color() { return rgba8(0,0,0,0); } //-------------------------------------------------------------------- static rgba8 from_wavelength(double wl, double gamma = 1.0) { return rgba8(rgba::from_wavelength(wl, gamma)); } //-------------------------------------------------------------------- rgba8(double wavelen, double gamma=1.0) { *this = from_wavelength(wavelen, gamma); } }; //------------------------------------------------------------------------ inline rgba8 rgba8_pre(unsigned r, unsigned g, unsigned b, unsigned a=1.0) { return rgba8(rgba8::pre, r, g, b, a); } //-------------------------------------------------------------------- inline rgba8 rgba8_pre(const rgba& c) { return rgba8(rgba8::pre, c); } //-------------------------------------------------------------------- inline rgba8 rgba8_pre(const rgba8& c, unsigned a) { return rgba8(rgba8::pre, c, a); } } #endif aggdraw-1.3.14/agg2/include/agg_conv_adaptor_vcgen.h000066400000000000000000000125451417726601400223260ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_CONV_ADAPTOR_VCGEN_INCLUDED #define AGG_CONV_ADAPTOR_VCGEN_INCLUDED #include "agg_basics.h" #include "agg_vertex_iterator.h" namespace agg { //------------------------------------------------------------null_markers struct null_markers { void remove_all() {} void add_vertex(double, double, unsigned) {} void prepare_src() {} void rewind(unsigned) {} unsigned vertex(double*, double*) { return path_cmd_stop; } typedef null_markers source_type; typedef vertex_iterator iterator; iterator begin(unsigned id) { return iterator(*this, id); } iterator end() { return iterator(path_cmd_stop); } }; //------------------------------------------------------conv_adaptor_vcgen template class conv_adaptor_vcgen { enum status { initial, accumulate, generate }; public: conv_adaptor_vcgen(VertexSource& source) : m_source(&source), m_status(initial) {} void set_source(VertexSource& source) { m_source = &source; } Generator& generator() { return m_generator; } const Generator& generator() const { return m_generator; } Markers& markers() { return m_markers; } const Markers& markers() const { return m_markers; } void rewind(unsigned id) { m_source->rewind(id); m_status = initial; } unsigned vertex(double* x, double* y); typedef conv_adaptor_vcgen source_type; typedef vertex_iterator iterator; iterator begin(unsigned id) { return iterator(*this, id); } iterator end() { return iterator(path_cmd_stop); } private: // Prohibit copying conv_adaptor_vcgen(const conv_adaptor_vcgen&); const conv_adaptor_vcgen& operator = (const conv_adaptor_vcgen&); VertexSource* m_source; Generator m_generator; Markers m_markers; status m_status; unsigned m_last_cmd; double m_start_x; double m_start_y; }; //------------------------------------------------------------------------ template unsigned conv_adaptor_vcgen::vertex(double* x, double* y) { unsigned cmd = path_cmd_stop; bool done = false; while(!done) { switch(m_status) { case initial: m_markers.remove_all(); m_last_cmd = m_source->vertex(&m_start_x, &m_start_y); m_status = accumulate; case accumulate: if(is_stop(m_last_cmd)) return path_cmd_stop; m_generator.remove_all(); m_generator.add_vertex(m_start_x, m_start_y, path_cmd_move_to); m_markers.add_vertex(m_start_x, m_start_y, path_cmd_move_to); for(;;) { cmd = m_source->vertex(x, y); if(is_vertex(cmd)) { m_last_cmd = cmd; if(is_move_to(cmd)) { m_start_x = *x; m_start_y = *y; break; } m_generator.add_vertex(*x, *y, cmd); m_markers.add_vertex(*x, *y, path_cmd_line_to); } else { if(is_stop(cmd)) { m_last_cmd = path_cmd_stop; break; } if(is_end_poly(cmd)) { m_generator.add_vertex(*x, *y, cmd); break; } } } m_generator.rewind(0); m_status = generate; case generate: cmd = m_generator.vertex(x, y); if(is_stop(cmd)) { m_status = accumulate; break; } done = true; break; } } return cmd; } } #endif aggdraw-1.3.14/agg2/include/agg_conv_adaptor_vpgen.h000066400000000000000000000073711417726601400223440ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_CONV_ADAPTOR_VPGEN_INCLUDED #define AGG_CONV_ADAPTOR_VPGEN_INCLUDED #include "agg_basics.h" #include "agg_vertex_iterator.h" namespace agg { //======================================================conv_adaptor_vpgen template class conv_adaptor_vpgen { public: conv_adaptor_vpgen(VertexSource& source) : m_source(&source) {} void set_source(VertexSource& source) { m_source = &source; } VPGen& vpgen() { return m_vpgen; } const VPGen& vpgen() const { return m_vpgen; } void rewind(unsigned path_id); unsigned vertex(double* x, double* y); typedef conv_adaptor_vpgen source_type; typedef vertex_iterator iterator; iterator begin(unsigned id) { return iterator(*this, id); } iterator end() { return iterator(path_cmd_stop); } private: conv_adaptor_vpgen(const conv_adaptor_vpgen&); const conv_adaptor_vpgen& operator = (const conv_adaptor_vpgen&); VertexSource* m_source; VPGen m_vpgen; double m_start_x; double m_start_y; unsigned m_poly_flags; }; //------------------------------------------------------------------------ template void conv_adaptor_vpgen::rewind(unsigned path_id) { m_source->rewind(path_id); m_vpgen.reset(); m_start_x = 0; m_start_y = 0; m_poly_flags = 0; } //------------------------------------------------------------------------ template unsigned conv_adaptor_vpgen::vertex(double* x, double* y) { unsigned cmd = path_cmd_stop; for(;;) { cmd = m_vpgen.vertex(x, y); if(!is_stop(cmd)) break; if(m_poly_flags) { cmd = m_poly_flags; m_poly_flags = 0; break; } double tx, ty; cmd = m_source->vertex(&tx, &ty); if(is_vertex(cmd)) { if(is_move_to(cmd)) { m_vpgen.move_to(tx, ty); m_start_x = tx; m_start_y = ty; } else { m_vpgen.line_to(tx, ty); } } else { if(is_end_poly(cmd)) { m_poly_flags = cmd; if(is_closed(cmd)) { m_vpgen.line_to(m_start_x, m_start_y); } } else { // The adaptor should be transparent to all unknown commands break; } } } return cmd; } } #endif aggdraw-1.3.14/agg2/include/agg_conv_bspline.h000066400000000000000000000032131417726601400211360ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_CONV_BSPLINE_INCLUDED #define AGG_CONV_BSPLINE_INCLUDED #include "agg_basics.h" #include "agg_vcgen_bspline.h" #include "agg_conv_adaptor_vcgen.h" namespace agg { //---------------------------------------------------------conv_bspline template struct conv_bspline : public conv_adaptor_vcgen { typedef conv_adaptor_vcgen base_type; conv_bspline(VertexSource& vs) : conv_adaptor_vcgen(vs) {} void interpolation_step(double v) { base_type::generator().interpolation_step(v); } double interpolation_step() const { return base_type::generator().interpolation_step(); } private: conv_bspline(const conv_bspline&); const conv_bspline& operator = (const conv_bspline&); }; } #endif aggdraw-1.3.14/agg2/include/agg_conv_clip_polygon.h000066400000000000000000000053521417726601400222060ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Polygon clipping converter // There an optimized Liang-Basky algorithm is used. // The algorithm doesn't optimize the degenerate edges, i.e. it will never // break a closed polygon into two or more ones, instead, there will be // degenerate edges coinciding with the respective clipping boundaries. // This is a sub-optimal solution, because that optimization would require // extra, rather expensive math while the rasterizer tolerates it quite well, // without any considerable overhead. // //---------------------------------------------------------------------------- #ifndef AGG_CONV_CLIP_POLYGON_INCLUDED #define AGG_CONV_CLIP_POLYGON_INCLUDED #include "agg_basics.h" #include "agg_conv_adaptor_vpgen.h" #include "agg_vpgen_clip_polygon.h" #include "agg_vertex_iterator.h" namespace agg { //=======================================================conv_clip_polygon template struct conv_clip_polygon : public conv_adaptor_vpgen { typedef conv_adaptor_vpgen base_type; conv_clip_polygon(VertexSource& vs) : conv_adaptor_vpgen(vs) {} void clip_box(double x1, double y1, double x2, double y2) { base_type::vpgen().clip_box(x1, y1, x2, y2); } double x1() const { return base_type::vpgen().x1(); } double y1() const { return base_type::vpgen().y1(); } double x2() const { return base_type::vpgen().x2(); } double y2() const { return base_type::vpgen().y2(); } typedef conv_clip_polygon source_type; typedef vertex_iterator iterator; iterator begin(unsigned id) { return iterator(*this, id); } iterator end() { return iterator(path_cmd_stop); } private: conv_clip_polygon(const conv_clip_polygon&); const conv_clip_polygon& operator = (const conv_clip_polygon&); }; } #endif aggdraw-1.3.14/agg2/include/agg_conv_close_polygon.h000066400000000000000000000074421417726601400223660ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_CONV_CLOSE_POLYGON_INCLUDED #define AGG_CONV_CLOSE_POLYGON_INCLUDED #include "agg_basics.h" #include "agg_vertex_iterator.h" namespace agg { //======================================================conv_close_polygon template class conv_close_polygon { public: conv_close_polygon(VertexSource& vs) : m_source(&vs) {} void set_source(VertexSource& source) { m_source = &source; } void rewind(unsigned path_id); unsigned vertex(double* x, double* y); typedef conv_close_polygon source_type; typedef vertex_iterator iterator; iterator begin(unsigned id) { return iterator(*this, id); } iterator end() { return iterator(path_cmd_stop); } private: conv_close_polygon(const conv_close_polygon&); const conv_close_polygon& operator = (const conv_close_polygon&); VertexSource* m_source; unsigned m_cmd[2]; double m_x[2]; double m_y[2]; unsigned m_vertex; bool m_line_to; }; //------------------------------------------------------------------------ template void conv_close_polygon::rewind(unsigned path_id) { m_source->rewind(path_id); m_vertex = 2; m_line_to = false; } //------------------------------------------------------------------------ template unsigned conv_close_polygon::vertex(double* x, double* y) { unsigned cmd = path_cmd_stop; for(;;) { if(m_vertex < 2) { *x = m_x[m_vertex]; *y = m_y[m_vertex]; cmd = m_cmd[m_vertex]; ++m_vertex; break; } cmd = m_source->vertex(x, y); if(is_end_poly(cmd)) { cmd |= path_flags_close; break; } if(is_stop(cmd)) { if(m_line_to) { m_cmd[0] = path_cmd_end_poly | path_flags_close; m_cmd[1] = path_cmd_stop; m_vertex = 0; m_line_to = false; continue; } break; } if(is_move_to(cmd)) { if(m_line_to) { m_x[0] = 0.0; m_y[0] = 0.0; m_cmd[0] = path_cmd_end_poly | path_flags_close; m_x[1] = *x; m_y[1] = *y; m_cmd[1] = cmd; m_vertex = 0; m_line_to = false; continue; } break; } if(is_vertex(cmd)) { m_line_to = true; break; } } return cmd; } } #endif aggdraw-1.3.14/agg2/include/agg_conv_concat.h000066400000000000000000000047071417726601400207620ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_CONV_CONCAT_INCLUDED #define AGG_CONV_CONCAT_INCLUDED #include "agg_basics.h" #include "agg_vertex_iterator.h" namespace agg { //=============================================================conv_concat // Concatenation of two paths. Usually used to combine lines or curves // with markers such as arrowheads template class conv_concat { public: conv_concat(VS1& source1, VS2& source2) : m_source1(&source1), m_source2(&source2), m_status(2) {} void set_source1(VS1& source) { m_source1 = &source; } void set_source2(VS2& source) { m_source2 = &source; } void rewind(unsigned id) { m_source1->rewind(id); m_source2->rewind(0); m_status = 0; } unsigned vertex(double* x, double* y) { unsigned cmd; if(m_status == 0) { cmd = m_source1->vertex(x, y); if(!is_stop(cmd)) return cmd; m_status = 1; } if(m_status == 1) { cmd = m_source2->vertex(x, y); if(!is_stop(cmd)) return cmd; m_status = 2; } return path_cmd_stop; } typedef conv_concat source_type; typedef vertex_iterator iterator; iterator begin(unsigned id) { return iterator(*this, id); } iterator end() { return iterator(path_cmd_stop); } private: conv_concat(const conv_concat&); const conv_concat& operator = (const conv_concat&); VS1* m_source1; VS2* m_source2; int m_status; }; } #endif aggdraw-1.3.14/agg2/include/agg_conv_contour.h000066400000000000000000000042261417726601400212000ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // conv_stroke // //---------------------------------------------------------------------------- #ifndef AGG_CONV_CONTOUR_INCLUDED #define AGG_CONV_CONTOUR_INCLUDED #include "agg_basics.h" #include "agg_vcgen_contour.h" #include "agg_conv_adaptor_vcgen.h" namespace agg { //-----------------------------------------------------------conv_contour template struct conv_contour : public conv_adaptor_vcgen { typedef conv_adaptor_vcgen base_type; conv_contour(VertexSource& vs) : conv_adaptor_vcgen(vs) { } void width(double w) { base_type::generator().width(w); } void miter_limit(double ml) { base_type::generator().miter_limit(ml); } void miter_limit_theta(double t) { base_type::generator().miter_limit_theta(t); } void auto_detect_orientation(bool v) { base_type::generator().auto_detect_orientation(v); } double width() const { return base_type::generator().width(); } double miter_limit() const { return base_type::generator().miter_limit(); } bool auto_detect_orientation() const { return base_type::generator().auto_detect_orientation(); } private: conv_contour(const conv_contour&); const conv_contour& operator = (const conv_contour&); }; } #endif aggdraw-1.3.14/agg2/include/agg_conv_curve.h000066400000000000000000000134721417726601400206360ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // classes conv_curve // //---------------------------------------------------------------------------- #ifndef AGG_CONV_CURVE_INCLUDED #define AGG_CONV_CURVE_INCLUDED #include "agg_basics.h" #include "agg_curves.h" namespace agg { //---------------------------------------------------------------conv_curve // Curve converter class. Any path storage can have Bezier curves defined // by their control points. There're two types of curves supported: curve3 // and curve4. Curve3 is a conic Bezier curve with 2 endpoints and 1 control // point. Curve4 has 2 control points (4 points in total) and can be used // to interpolate more complicated curves. Curve4, unlike curve3 can be used // to approximate arcs, both curcular and elliptical. Curves are approximated // with straight lines and one of the approaches is just to store the whole // sequence of vertices that approximate our curve. It takes additional // memory, and at the same time the consecutive vertices can be calculated // on demand. // // Initially, path storages are not suppose to keep all the vertices of the // curves (although, nothig prevents us from doing so). Instead, path_storage // keeps only vertices, needed to calculate a curve on demand. Those vertices // are marked with special commands. So, if the path_storage contains curves // (which are not real curves yet), and we render this storage directly, // all we will see is only 2 or 3 straight line segments (for curve3 and // curve4 respectively). If we need to see real curves drawn we need to // include this class into the conversion pipeline. // // Class conv_curve recognizes commands path_cmd_curve3 and path_cmd_curve4 // and converts these vertices into a move_to/line_to sequence. //----------------------------------------------------------------------- template class conv_curve { public: conv_curve(VertexSource& source) : m_source(&source), m_last_x(0.0), m_last_y(0.0) {} void set_source(VertexSource& source) { m_source = &source; } void approximation_scale(double s) { m_curve3.approximation_scale(s); m_curve4.approximation_scale(s); } double approximation_scale() const { return m_curve3.approximation_scale(); } void rewind(unsigned id); unsigned vertex(double* x, double* y); typedef conv_curve source_type; typedef vertex_iterator iterator; iterator begin(unsigned id) { return iterator(*this, id); } iterator end() { return iterator(path_cmd_stop); } private: conv_curve(const conv_curve&); const conv_curve& operator = (const conv_curve&); VertexSource* m_source; double m_last_x; double m_last_y; curve3 m_curve3; curve4 m_curve4; }; //------------------------------------------------------------------------ template void conv_curve::rewind(unsigned id) { m_source->rewind(id); m_last_x = 0.0; m_last_y = 0.0; m_curve3.reset(); m_curve4.reset(); } //------------------------------------------------------------------------ template unsigned conv_curve::vertex(double* x, double* y) { if(!is_stop(m_curve3.vertex(x, y))) { m_last_x = *x; m_last_y = *y; return path_cmd_line_to; } if(!is_stop(m_curve4.vertex(x, y))) { m_last_x = *x; m_last_y = *y; return path_cmd_line_to; } double ct2_x; double ct2_y; double end_x; double end_y; unsigned cmd = m_source->vertex(x, y); switch(cmd) { case path_cmd_move_to: case path_cmd_line_to: m_last_x = *x; m_last_y = *y; default: break; case path_cmd_curve3: m_source->vertex(&end_x, &end_y); m_curve3.init(m_last_x, m_last_y, *x, *y, end_x, end_y); m_curve3.vertex(x, y); // First call returns path_cmd_move_to m_curve3.vertex(x, y); // This is the first vertex of the curve cmd = path_cmd_line_to; break; case path_cmd_curve4: m_source->vertex(&ct2_x, &ct2_y); m_source->vertex(&end_x, &end_y); m_curve4.init(m_last_x, m_last_y, *x, *y, ct2_x, ct2_y, end_x, end_y); m_curve4.vertex(x, y); // First call returns path_cmd_move_to m_curve4.vertex(x, y); // This is the first vertex of the curve cmd = path_cmd_line_to; break; } return cmd; } } #endif aggdraw-1.3.14/agg2/include/agg_conv_dash.h000066400000000000000000000042221417726601400204220ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // conv_dash // //---------------------------------------------------------------------------- #ifndef AGG_CONV_DASH_INCLUDED #define AGG_CONV_DASH_INCLUDED #include "agg_basics.h" #include "agg_vcgen_dash.h" #include "agg_conv_adaptor_vcgen.h" namespace agg { //---------------------------------------------------------------conv_dash template struct conv_dash : public conv_adaptor_vcgen { typedef Markers marker_type; typedef conv_adaptor_vcgen base_type; conv_dash(VertexSource& vs) : conv_adaptor_vcgen(vs) { } void remove_all_dashes() { base_type::generator().remove_all_dashes(); } void add_dash(double dash_len, double gap_len) { base_type::generator().add_dash(dash_len, gap_len); } void dash_start(double ds) { base_type::generator().dash_start(ds); } void shorten(double s) { base_type::generator().shorten(s); } double shorten() const { return base_type::generator().shorten(); } private: conv_dash(const conv_dash&); const conv_dash& operator = (const conv_dash&); }; } #endif aggdraw-1.3.14/agg2/include/agg_conv_gpc.h000066400000000000000000000312221417726601400202540ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // General Polygon Clipper based on the GPC library by Alan Murta // Union, Intersection, XOR, A-B, B-A // Contact the author if you intend to use it in commercial applications! // http://www.cs.man.ac.uk/aig/staff/alan/software/ // Alan Murta (email: gpc@cs.man.ac.uk) // //---------------------------------------------------------------------------- #ifndef AGG_CONV_GPC_INCLUDED #define AGG_CONV_GPC_INCLUDED #include #include "agg_basics.h" #include "agg_array.h" #include "agg_vertex_iterator.h" extern "C" { #include "gpc.h" } namespace agg { enum gpc_op_e { gpc_or, gpc_and, gpc_xor, gpc_a_minus_b, gpc_b_minus_a }; //================================================================conv_gpc template class conv_gpc { enum status { status_move_to, status_line_to, status_stop }; struct contour_header_type { int num_vertices; int hole_flag; gpc_vertex* vertices; }; typedef pod_deque vertex_array_type; typedef pod_deque contour_header_array_type; public: typedef VSA source_a_type; typedef VSB source_b_type; typedef conv_gpc self_type; ~conv_gpc() { free_gpc_data(); } conv_gpc(source_a_type& a, source_b_type& b, gpc_op_e op = gpc_or) : m_src_a(&a), m_src_b(&b), m_status(status_move_to), m_vertex(-1), m_contour(-1), m_operation(op) { memset(&m_poly_a, 0, sizeof(m_poly_a)); memset(&m_poly_b, 0, sizeof(m_poly_b)); memset(&m_result, 0, sizeof(m_result)); } void set_source1(VSA& source) { m_src_a = &source; } void set_source2(VSB& source) { m_src_b = &source; } void operation(gpc_op_e v) { m_operation = v; } // Vertex Source Interface void rewind(unsigned id); unsigned vertex(double* x, double* y); // Iterator typedef vertex_iterator iterator; iterator begin(unsigned id) { return iterator(*this, id); } iterator end() { return iterator(path_cmd_stop); } private: conv_gpc(const conv_gpc&); const conv_gpc& operator = (const conv_gpc&); //-------------------------------------------------------------------- void free_polygon(gpc_polygon& p); void free_result(); void free_gpc_data(); void start_contour(); void add_vertex(double x, double y); void end_contour(unsigned orientation); void make_polygon(gpc_polygon& p); void start_extracting(); bool next_contour(); bool next_vertex(double* x, double* y); //-------------------------------------------------------------------- template void add(VS& src, gpc_polygon& p) { unsigned cmd; double x, y; double start_x = 0.0; double start_y = 0.0; bool line_to = false; unsigned orientation = 0; m_contour_accumulator.remove_all(); while(!is_stop(cmd = src.vertex(&x, &y))) { if(is_vertex(cmd)) { if(is_move_to(cmd)) { if(line_to) { end_contour(orientation); orientation = 0; } start_contour(); start_x = x; start_y = y; } add_vertex(x, y); line_to = true; } else { if(is_end_poly(cmd)) { orientation = get_orientation(cmd); if(line_to && is_closed(cmd)) { add_vertex(start_x, start_y); } } } } if(line_to) { end_contour(orientation); } make_polygon(p); } private: //-------------------------------------------------------------------- source_a_type* m_src_a; source_b_type* m_src_b; status m_status; int m_vertex; int m_contour; gpc_op_e m_operation; vertex_array_type m_vertex_accumulator; contour_header_array_type m_contour_accumulator; gpc_polygon m_poly_a; gpc_polygon m_poly_b; gpc_polygon m_result; }; //------------------------------------------------------------------------ template void conv_gpc::free_polygon(gpc_polygon& p) { int i; for(i = 0; i < p.num_contours; i++) { delete [] p.contour[i].vertex; } delete [] p.hole; delete [] p.contour; memset(&p, 0, sizeof(gpc_polygon)); } //------------------------------------------------------------------------ template void conv_gpc::free_result() { if(m_result.contour) { gpc_free_polygon(&m_result); } memset(&m_result, 0, sizeof(m_result)); } //------------------------------------------------------------------------ template void conv_gpc::free_gpc_data() { free_polygon(m_poly_a); free_polygon(m_poly_b); free_result(); } //------------------------------------------------------------------------ template void conv_gpc::start_contour() { contour_header_type h; memset(&h, 0, sizeof(h)); m_contour_accumulator.add(h); m_vertex_accumulator.remove_all(); } //------------------------------------------------------------------------ template inline void conv_gpc::add_vertex(double x, double y) { gpc_vertex v; v.x = x; v.y = y; m_vertex_accumulator.add(v); } //------------------------------------------------------------------------ template void conv_gpc::end_contour(unsigned orientation) { if(m_contour_accumulator.size()) { if(m_vertex_accumulator.size() > 2) { contour_header_type& h = m_contour_accumulator[m_contour_accumulator.size() - 1]; h.num_vertices = m_vertex_accumulator.size(); h.hole_flag = 0; // TO DO: Clarify the "holes" //if(is_cw(orientation)) h.hole_flag = 1; h.vertices = new gpc_vertex [h.num_vertices]; gpc_vertex* d = h.vertices; int i; for(i = 0; i < h.num_vertices; i++) { const gpc_vertex& s = m_vertex_accumulator[i]; d->x = s.x; d->y = s.y; ++d; } } else { m_vertex_accumulator.remove_last(); } } } //------------------------------------------------------------------------ template void conv_gpc::make_polygon(gpc_polygon& p) { free_polygon(p); if(m_contour_accumulator.size()) { p.num_contours = m_contour_accumulator.size(); // TO DO: Clarify the "holes" //p.hole = new int[p.num_contours]; p.hole = 0; p.contour = new gpc_vertex_list[p.num_contours]; int i; //int* ph = p.hole; gpc_vertex_list* pv = p.contour; for(i = 0; i < p.num_contours; i++) { const contour_header_type& h = m_contour_accumulator[i]; // *ph++ = h.hole_flag; pv->num_vertices = h.num_vertices; pv->vertex = h.vertices; ++pv; } } } //------------------------------------------------------------------------ template void conv_gpc::start_extracting() { m_status = status_move_to; m_contour = -1; m_vertex = -1; } //------------------------------------------------------------------------ template bool conv_gpc::next_contour() { if(++m_contour < m_result.num_contours) { m_vertex = -1; return true; } return false; } //------------------------------------------------------------------------ template inline bool conv_gpc::next_vertex(double* x, double* y) { const gpc_vertex_list& vlist = m_result.contour[m_contour]; if(++m_vertex < vlist.num_vertices) { const gpc_vertex& v = vlist.vertex[m_vertex]; *x = v.x; *y = v.y; return true; } return false; } //------------------------------------------------------------------------ template void conv_gpc::rewind(unsigned id) { free_result(); m_src_a->rewind(id); m_src_b->rewind(id); add(*m_src_a, m_poly_a); add(*m_src_b, m_poly_b); switch(m_operation) { case gpc_or: gpc_polygon_clip(GPC_UNION, &m_poly_a, &m_poly_b, &m_result); break; case gpc_and: gpc_polygon_clip(GPC_INT, &m_poly_a, &m_poly_b, &m_result); break; case gpc_xor: gpc_polygon_clip(GPC_XOR, &m_poly_a, &m_poly_b, &m_result); break; case gpc_a_minus_b: gpc_polygon_clip(GPC_DIFF, &m_poly_a, &m_poly_b, &m_result); break; case gpc_b_minus_a: gpc_polygon_clip(GPC_DIFF, &m_poly_b, &m_poly_a, &m_result); break; } start_extracting(); } //------------------------------------------------------------------------ template unsigned conv_gpc::vertex(double* x, double* y) { if(m_status == status_move_to) { if(next_contour()) { if(next_vertex(x, y)) { m_status = status_line_to; return path_cmd_move_to; } m_status = status_stop; return path_cmd_end_poly | path_flags_close; } } else { if(next_vertex(x, y)) { return path_cmd_line_to; } else { m_status = status_move_to; } return path_cmd_end_poly | path_flags_close; } return path_cmd_stop; } } #endif aggdraw-1.3.14/agg2/include/agg_conv_marker.h000066400000000000000000000112671417726601400207730ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // conv_marker // //---------------------------------------------------------------------------- #ifndef AGG_CONV_MARKER_INCLUDED #define AGG_CONV_MARKER_INCLUDED #include "agg_basics.h" #include "agg_trans_affine.h" #include "agg_vertex_iterator.h" namespace agg { //-------------------------------------------------------------conv_marker template class conv_marker { public: conv_marker(MarkerLocator& ml, MarkerShapes& ms); trans_affine& transform() { return m_transform; } const trans_affine& transform() const { return m_transform; } void rewind(unsigned id); unsigned vertex(double* x, double* y); typedef conv_marker source_type; typedef vertex_iterator iterator; iterator begin(unsigned id) { return iterator(*this, id); } iterator end() { return iterator(path_cmd_stop); } private: conv_marker(const conv_marker&); const conv_marker& operator = (const conv_marker&); enum status_e { initial, markers, polygon, stop }; MarkerLocator* m_marker_locator; MarkerShapes* m_marker_shapes; trans_affine m_transform; trans_affine m_mtx; status_e m_status; unsigned m_marker; unsigned m_num_markers; }; //------------------------------------------------------------------------ template conv_marker::conv_marker(MarkerLocator& ml, MarkerShapes& ms) : m_marker_locator(&ml), m_marker_shapes(&ms), m_status(initial), m_marker(0), m_num_markers(1) { } //------------------------------------------------------------------------ template void conv_marker::rewind(unsigned) { m_status = initial; m_marker = 0; m_num_markers = 1; } //------------------------------------------------------------------------ template unsigned conv_marker::vertex(double* x, double* y) { unsigned cmd = path_cmd_move_to; double x1, y1, x2, y2; while(!is_stop(cmd)) { switch(m_status) { case initial: if(m_num_markers == 0) { cmd = path_cmd_stop; break; } m_marker_locator->rewind(m_marker); ++m_marker; m_num_markers = 0; m_status = markers; case markers: if(is_stop(m_marker_locator->vertex(&x1, &y1))) { m_status = initial; break; } if(is_stop(m_marker_locator->vertex(&x2, &y2))) { m_status = initial; break; } ++m_num_markers; m_mtx = m_transform; m_mtx *= trans_affine_rotation(atan2(y2 - y1, x2 - x1)); m_mtx *= trans_affine_translation(x1, y1); m_marker_shapes->rewind(m_marker - 1); m_status = polygon; case polygon: cmd = m_marker_shapes->vertex(x, y); if(is_stop(cmd)) { cmd = path_cmd_move_to; m_status = markers; break; } m_mtx.transform(x, y); return cmd; case stop: cmd = path_cmd_stop; break; } } return cmd; } } #endif aggdraw-1.3.14/agg2/include/agg_conv_marker_adaptor.h000066400000000000000000000035031417726601400224770ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_CONV_MARKER_ADAPTOR_INCLUDED #define AGG_CONV_MARKER_ADAPTOR_INCLUDED #include "agg_basics.h" #include "agg_conv_adaptor_vcgen.h" #include "agg_vcgen_vertex_sequence.h" namespace agg { //=====================================================conv_marker_adaptor template struct conv_marker_adaptor : public conv_adaptor_vcgen { typedef Markers marker_type; typedef conv_adaptor_vcgen base_type; conv_marker_adaptor(VertexSource& vs) : conv_adaptor_vcgen(vs) { } void shorten(double s) { base_type::generator().shorten(s); } double shorten() const { return base_type::generator().shorten(); } private: conv_marker_adaptor(const conv_marker_adaptor&); const conv_marker_adaptor& operator = (const conv_marker_adaptor&); }; } #endif aggdraw-1.3.14/agg2/include/agg_conv_segmentator.h000066400000000000000000000033001417726601400220270ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_CONV_SEGMENTATOR_INCLUDED #define AGG_CONV_SEGMENTATOR_INCLUDED #include "agg_basics.h" #include "agg_conv_adaptor_vpgen.h" #include "agg_vpgen_segmentator.h" namespace agg { //========================================================conv_segmentator template struct conv_segmentator : public conv_adaptor_vpgen { typedef conv_adaptor_vpgen base_type; conv_segmentator(VertexSource& vs) : conv_adaptor_vpgen(vs) {} void approximation_scale(double s) { base_type::vpgen().approximation_scale(s); } double approximation_scale() const { return base_type::vpgen().approximation_scale(); } private: conv_segmentator(const conv_segmentator&); const conv_segmentator& operator = (const conv_segmentator&); }; } #endif aggdraw-1.3.14/agg2/include/agg_conv_shorten_path.h000066400000000000000000000033041417726601400222010ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_CONV_SHORTEN_PATH_INCLUDED #define AGG_CONV_SHORTEN_PATH_INCLUDED #include "agg_basics.h" #include "agg_conv_adaptor_vcgen.h" #include "agg_vcgen_vertex_sequence.h" namespace agg { //=======================================================conv_shorten_path template class conv_shorten_path : public conv_adaptor_vcgen { public: typedef conv_adaptor_vcgen base_type; conv_shorten_path(VertexSource& vs) : conv_adaptor_vcgen(vs) { } void shorten(double s) { base_type::generator().shorten(s); } double shorten() const { return base_type::generator().shorten(); } private: conv_shorten_path(const conv_shorten_path&); const conv_shorten_path& operator = (const conv_shorten_path&); }; } #endif aggdraw-1.3.14/agg2/include/agg_conv_smooth_poly1.h000066400000000000000000000052131417726601400221410ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Smooth polygon generator // //---------------------------------------------------------------------------- #ifndef AGG_CONV_SMOOTH_POLY1_INCLUDED #define AGG_CONV_SMOOTH_POLY1_INCLUDED #include "agg_basics.h" #include "agg_vcgen_smooth_poly1.h" #include "agg_conv_adaptor_vcgen.h" #include "agg_conv_curve.h" namespace agg { //-------------------------------------------------------conv_smooth_poly1 template struct conv_smooth_poly1 : public conv_adaptor_vcgen { typedef conv_adaptor_vcgen base_type; conv_smooth_poly1(VertexSource& vs) : conv_adaptor_vcgen(vs) { } void smooth_value(double v) { base_type::generator().smooth_value(v); } double smooth_value() const { return base_type::generator().smooth_value(); } private: conv_smooth_poly1(const conv_smooth_poly1&); const conv_smooth_poly1& operator = (const conv_smooth_poly1&); }; //-------------------------------------------------conv_smooth_poly1_curve template struct conv_smooth_poly1_curve : public conv_curve > { conv_smooth_poly1_curve(VertexSource& vs) : conv_curve >(m_smooth), m_smooth(vs) { } void smooth_value(double v) { m_smooth.generator().smooth_value(v); } double smooth_value() const { return m_smooth.generator().smooth_value(); } private: conv_smooth_poly1_curve(const conv_smooth_poly1_curve&); const conv_smooth_poly1_curve& operator = (const conv_smooth_poly1_curve&); conv_smooth_poly1 m_smooth; }; } #endif aggdraw-1.3.14/agg2/include/agg_conv_stroke.h000066400000000000000000000054241417726601400210170ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // conv_stroke // //---------------------------------------------------------------------------- #ifndef AGG_CONV_STROKE_INCLUDED #define AGG_CONV_STROKE_INCLUDED #include "agg_basics.h" #include "agg_vcgen_stroke.h" #include "agg_conv_adaptor_vcgen.h" namespace agg { //-------------------------------------------------------------conv_stroke template struct conv_stroke : public conv_adaptor_vcgen { typedef Markers marker_type; typedef conv_adaptor_vcgen base_type; conv_stroke(VertexSource& vs) : conv_adaptor_vcgen(vs) { } void line_cap(vcgen_stroke::line_cap_e lc) { base_type::generator().line_cap(lc); } void line_join(vcgen_stroke::line_join_e lj) { base_type::generator().line_join(lj); } vcgen_stroke::line_cap_e line_cap() const { return base_type::generator().line_cap(); } vcgen_stroke::line_join_e line_join() const { return base_type::generator().line_join(); } void width(double w) { base_type::generator().width(w); } void miter_limit(double ml) { base_type::generator().miter_limit(ml); } void miter_limit_theta(double t) { base_type::generator().miter_limit_theta(t); } void approximation_scale(double as) { base_type::generator().approximation_scale(as); } double width() const { return base_type::generator().width(); } double miter_limit() const { return base_type::generator().miter_limit(); } double approximation_scale() const { return base_type::generator().approximation_scale(); } void shorten(double s) { base_type::generator().shorten(s); } double shorten() const { return base_type::generator().shorten(); } private: conv_stroke(const conv_stroke&); const conv_stroke& operator = (const conv_stroke&); }; } #endif aggdraw-1.3.14/agg2/include/agg_conv_transform.h000066400000000000000000000044501417726601400215210ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // class conv_transform // //---------------------------------------------------------------------------- #ifndef AGG_CONV_TRANSFORM_INCLUDED #define AGG_CONV_TRANSFORM_INCLUDED #include "agg_basics.h" #include "agg_trans_affine.h" #include "agg_vertex_iterator.h" namespace agg { //----------------------------------------------------------conv_transform template class conv_transform { public: conv_transform(VertexSource& source, const Transformer& tr) : m_source(&source), m_trans(&tr) {} void set_source(VertexSource& source) { m_source = &source; } void rewind(unsigned id) { m_source->rewind(id); } unsigned vertex(double* x, double* y) { unsigned cmd = m_source->vertex(x, y); if(is_vertex(cmd)) { m_trans->transform(x, y); } return cmd; } void transformer(const Transformer& tr) { m_trans = &tr; } typedef conv_transform source_type; typedef vertex_iterator iterator; iterator begin(unsigned id) { return iterator(*this, id); } iterator end() { return iterator(path_cmd_stop); } private: conv_transform(const conv_transform&); const conv_transform& operator = (const conv_transform&); VertexSource* m_source; const Transformer* m_trans; }; } #endif aggdraw-1.3.14/agg2/include/agg_conv_unclose_polygon.h000066400000000000000000000037001417726601400227220ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_CONV_UNCLOSE_POLYGON_INCLUDED #define AGG_CONV_UNCLOSE_POLYGON_INCLUDED #include "agg_basics.h" #include "agg_vertex_iterator.h" namespace agg { //====================================================conv_unclose_polygon template class conv_unclose_polygon { public: conv_unclose_polygon(VertexSource& vs) : m_source(&vs) {} void set_source(VertexSource& source) { m_source = &source; } void rewind(unsigned path_id) { m_source->rewind(path_id); } unsigned vertex(double* x, double* y) { unsigned cmd = m_source->vertex(x, y); if(is_end_poly(cmd)) cmd &= ~path_flags_close; return cmd; } typedef conv_unclose_polygon source_type; typedef vertex_iterator iterator; iterator begin(unsigned id) { return iterator(*this, id); } iterator end() { return iterator(path_cmd_stop); } private: conv_unclose_polygon(const conv_unclose_polygon&); const conv_unclose_polygon& operator = (const conv_unclose_polygon&); VertexSource* m_source; }; } #endif aggdraw-1.3.14/agg2/include/agg_curves.h000066400000000000000000000102331417726601400177640ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // classes curve3 and curve4 // //---------------------------------------------------------------------------- #ifndef AGG_CURVES_INCLUDED #define AGG_CURVES_INCLUDED #include "agg_basics.h" #include "agg_vertex_iterator.h" namespace agg { // See Implemantation agg_curves.cpp //------------------------------------------------------------------curve3 class curve3 { public: curve3() : m_num_steps(0), m_step(0), m_scale(1.0) { } curve3(double x1, double y1, double x2, double y2, double x3, double y3) : m_num_steps(0), m_step(0), m_scale(1.0) { init(x1, y1, x2, y2, x3, y3); } void reset() { m_num_steps = 0; m_step = -1; } void init(double x1, double y1, double x2, double y2, double x3, double y3); void approximation_scale(double s) { m_scale = s; } double approximation_scale() const { return m_scale; } void rewind(unsigned id); unsigned vertex(double* x, double* y); typedef curve3 source_type; typedef vertex_iterator iterator; iterator begin(unsigned id) { return iterator(*this, id); } iterator end() { return iterator(path_cmd_stop); } private: int m_num_steps; int m_step; double m_scale; double m_start_x; double m_start_y; double m_end_x; double m_end_y; double m_fx; double m_fy; double m_dfx; double m_dfy; double m_ddfx; double m_ddfy; double m_saved_fx; double m_saved_fy; double m_saved_dfx; double m_saved_dfy; }; //-----------------------------------------------------------------curve4 class curve4 { public: curve4() : m_num_steps(0), m_step(0), m_scale(1.0) { } curve4(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) : m_num_steps(0), m_step(0), m_scale(1.0) { init(x1, y1, x2, y2, x3, y3, x4, y4); } void reset() { m_num_steps = 0; m_step = -1; } void init(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4); void approximation_scale(double s) { m_scale = s; } double approximation_scale() const { return m_scale; } void rewind(unsigned id); unsigned vertex(double* x, double* y); typedef curve4 source_type; typedef vertex_iterator iterator; iterator begin(unsigned id) { return iterator(*this, id); } iterator end() { return iterator(path_cmd_stop); } private: int m_num_steps; int m_step; double m_scale; double m_start_x; double m_start_y; double m_end_x; double m_end_y; double m_fx; double m_fy; double m_dfx; double m_dfy; double m_ddfx; double m_ddfy; double m_dddfx; double m_dddfy; double m_saved_fx; double m_saved_fy; double m_saved_dfx; double m_saved_dfy; double m_saved_ddfx; double m_saved_ddfy; }; } #endif aggdraw-1.3.14/agg2/include/agg_dda_line.h000066400000000000000000000203441417726601400202200ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // classes dda_line_interpolator, dda2_line_interpolator // //---------------------------------------------------------------------------- #ifndef AGG_DDA_LINE_INCLUDED #define AGG_DDA_LINE_INCLUDED #include #include "agg_basics.h" namespace agg { //===================================================dda_line_interpolator template class dda_line_interpolator { public: //-------------------------------------------------------------------- dda_line_interpolator() {} //-------------------------------------------------------------------- dda_line_interpolator(int y1, int y2, unsigned count) : m_y(y1), m_inc(((y2 - y1) << FractionShift) / int(count)), m_dy(0) { } //-------------------------------------------------------------------- void operator ++ () { m_dy += m_inc; } //-------------------------------------------------------------------- void operator -- () { m_dy -= m_inc; } //-------------------------------------------------------------------- void operator += (unsigned n) { m_dy += m_inc * n; } //-------------------------------------------------------------------- void operator -= (unsigned n) { m_dy -= m_inc * n; } //-------------------------------------------------------------------- int y() const { return m_y + (m_dy >> (FractionShift-YShift)); } int dy() const { return m_dy; } private: int m_y; int m_inc; int m_dy; }; //=================================================dda2_line_interpolator class dda2_line_interpolator { public: typedef int save_data_type; enum { save_size = 2 }; //-------------------------------------------------------------------- dda2_line_interpolator() {} //-------------------------------------------- Forward-adjusted line dda2_line_interpolator(int y1, int y2, int count) : m_cnt(count <= 0 ? 1 : count), m_lft((y2 - y1) / m_cnt), m_rem((y2 - y1) % m_cnt), m_mod(m_rem), m_y(y1) { if(m_mod <= 0) { m_mod += count; m_rem += count; m_lft--; } m_mod -= count; } //-------------------------------------------- Backward-adjusted line dda2_line_interpolator(int y1, int y2, int count, int) : m_cnt(count <= 0 ? 1 : count), m_lft((y2 - y1) / m_cnt), m_rem((y2 - y1) % m_cnt), m_mod(m_rem), m_y(y1) { if(m_mod <= 0) { m_mod += count; m_rem += count; m_lft--; } } //-------------------------------------------- Backward-adjusted line dda2_line_interpolator(int y, int count) : m_cnt(count <= 0 ? 1 : count), m_lft(y / m_cnt), m_rem(y % m_cnt), m_mod(m_rem), m_y(0) { if(m_mod <= 0) { m_mod += count; m_rem += count; m_lft--; } } //-------------------------------------------------------------------- void save(save_data_type* data) const { data[0] = m_mod; data[1] = m_y; } //-------------------------------------------------------------------- void load(const save_data_type* data) { m_mod = data[0]; m_y = data[1]; } //-------------------------------------------------------------------- void operator++() { m_mod += m_rem; m_y += m_lft; if(m_mod > 0) { m_mod -= m_cnt; m_y++; } } //-------------------------------------------------------------------- void operator--() { if(m_mod <= m_rem) { m_mod += m_cnt; m_y--; } m_mod -= m_rem; m_y -= m_lft; } //-------------------------------------------------------------------- void adjust_forward() { m_mod -= m_cnt; } //-------------------------------------------------------------------- void adjust_backward() { m_mod += m_cnt; } //-------------------------------------------------------------------- int mod() const { return m_mod; } int rem() const { return m_rem; } int lft() const { return m_lft; } //-------------------------------------------------------------------- int y() const { return m_y; } private: int m_cnt; int m_lft; int m_rem; int m_mod; int m_y; }; //---------------------------------------------line_bresenham_interpolator class line_bresenham_interpolator { public: enum { subpixel_shift = 8, subpixel_size = 1 << subpixel_shift, subpixel_mask = subpixel_size - 1 }; //-------------------------------------------------------------------- static int line_lr(int v) { return v >> subpixel_shift; } //-------------------------------------------------------------------- line_bresenham_interpolator(int x1, int y1, int x2, int y2) : m_x1_lr(line_lr(x1)), m_y1_lr(line_lr(y1)), m_x2_lr(line_lr(x2)), m_y2_lr(line_lr(y2)), m_ver(abs(m_x2_lr - m_x1_lr) < abs(m_y2_lr - m_y1_lr)), m_len(m_ver ? abs(m_y2_lr - m_y1_lr) : abs(m_x2_lr - m_x1_lr)), m_inc(m_ver ? ((y2 > y1) ? 1 : -1) : ((x2 > x1) ? 1 : -1)), m_interpolator(m_ver ? x1 : y1, m_ver ? x2 : y2, m_len) { } //-------------------------------------------------------------------- bool is_ver() const { return m_ver; } unsigned len() const { return m_len; } int inc() const { return m_inc; } //-------------------------------------------------------------------- void hstep() { ++m_interpolator; m_x1_lr += m_inc; } //-------------------------------------------------------------------- void vstep() { ++m_interpolator; m_y1_lr += m_inc; } //-------------------------------------------------------------------- int x1() const { return m_x1_lr; } int y1() const { return m_y1_lr; } int x2() const { return line_lr(m_interpolator.y()); } int y2() const { return line_lr(m_interpolator.y()); } int x2_hr() const { return m_interpolator.y(); } int y2_hr() const { return m_interpolator.y(); } private: int m_x1_lr; int m_y1_lr; int m_x2_lr; int m_y2_lr; bool m_ver; unsigned m_len; int m_inc; dda2_line_interpolator m_interpolator; }; } #endif aggdraw-1.3.14/agg2/include/agg_ellipse.h000066400000000000000000000056321417726601400201210ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // class ellipse // //---------------------------------------------------------------------------- #ifndef AGG_ELLIPSE_INCLUDED #define AGG_ELLIPSE_INCLUDED #include "agg_basics.h" #include namespace agg { //----------------------------------------------------------------ellipse class ellipse { public: ellipse() : m_x(0.0), m_y(0.0), m_rx(1.0), m_ry(1.0), m_num(4), m_step(0) {} ellipse(double x, double y, double rx, double ry, unsigned num_steps) : m_x(x), m_y(y), m_rx(rx), m_ry(ry), m_num(num_steps), m_step(0) {} void init(double x, double y, double rx, double ry, unsigned num_steps); void approximation_scale(double scale); void rewind(unsigned id); unsigned vertex(double* x, double* y); private: double m_x; double m_y; double m_rx; double m_ry; unsigned m_num; unsigned m_step; }; //------------------------------------------------------------------------ inline void ellipse::init(double x, double y, double rx, double ry, unsigned num_steps) { m_x = x; m_y = y; m_rx = rx; m_ry = ry; m_num = num_steps; m_step = 0; } //------------------------------------------------------------------------ inline void ellipse::approximation_scale(double scale) { m_num = unsigned((fabs(m_rx) + fabs(m_ry) + 6.0) * scale); if(m_num < 6) m_num = 6; } //------------------------------------------------------------------------ inline void ellipse::rewind(unsigned) { m_step = 0; } //------------------------------------------------------------------------ inline unsigned ellipse::vertex(double* x, double* y) { if(m_step == m_num) { ++m_step; return path_cmd_end_poly | path_flags_close | path_flags_ccw; } if(m_step > m_num) return path_cmd_stop; double angle = double(m_step) / double(m_num) * 2.0 * pi; *x = m_x + cos(angle) * m_rx; *y = m_y + sin(angle) * m_ry; m_step++; return ((m_step == 1) ? path_cmd_move_to : path_cmd_line_to); } } #endif aggdraw-1.3.14/agg2/include/agg_ellipse_bresenham.h000066400000000000000000000054231417726601400221430ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Simple Bresenham interpolator for ellipsees // //---------------------------------------------------------------------------- #ifndef AGG_ELLIPSE_BRESENHAM_INCLUDED #define AGG_ELLIPSE_BRESENHAM_INCLUDED #include "agg_basics.h" namespace agg { //------------------------------------------ellipse_bresenham_interpolator class ellipse_bresenham_interpolator { public: ellipse_bresenham_interpolator(int rx, int ry) : m_rx2(rx * rx), m_ry2(ry * ry), m_two_rx2(m_rx2 << 1), m_two_ry2(m_ry2 << 1), m_dx(0), m_dy(0), m_inc_x(0), m_inc_y(-ry * m_two_rx2), m_cur_f(0) {} int dx() const { return m_dx; } int dy() const { return m_dy; } void operator++ () { int mx, my, mxy, min_m; int fx, fy, fxy; mx = fx = m_cur_f + m_inc_x + m_ry2; if(mx < 0) mx = -mx; my = fy = m_cur_f + m_inc_y + m_rx2; if(my < 0) my = -my; mxy = fxy = m_cur_f + m_inc_x + m_ry2 + m_inc_y + m_rx2; if(mxy < 0) mxy = -mxy; min_m = mx; bool flag = true; if(min_m > my) { min_m = my; flag = false; } m_dx = m_dy = 0; if(min_m > mxy) { m_inc_x += m_two_ry2; m_inc_y += m_two_rx2; m_cur_f = fxy; m_dx = 1; m_dy = 1; return; } if(flag) { m_inc_x += m_two_ry2; m_cur_f = fx; m_dx = 1; return; } m_inc_y += m_two_rx2; m_cur_f = fy; m_dy = 1; } private: int m_rx2; int m_ry2; int m_two_rx2; int m_two_ry2; int m_dx; int m_dy; int m_inc_x; int m_inc_y; int m_cur_f; }; } #endif aggdraw-1.3.14/agg2/include/agg_embedded_raster_fonts.h000066400000000000000000000041431417726601400230020ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_EMBEDDED_RASTER_FONTS_INCLUDED #define AGG_EMBEDDED_RASTER_FONTS_INCLUDED #include "agg_basics.h" namespace agg { extern const int8u gse4x6[]; extern const int8u gse4x8[]; extern const int8u gse5x7[]; extern const int8u gse5x9[]; extern const int8u gse6x12[]; extern const int8u gse6x9[]; extern const int8u gse7x11[]; extern const int8u gse7x11_bold[]; extern const int8u gse7x15[]; extern const int8u gse7x15_bold[]; extern const int8u gse8x16[]; extern const int8u gse8x16_bold[]; extern const int8u mcs11_prop[]; extern const int8u mcs11_prop_condensed[]; extern const int8u mcs12_prop[]; extern const int8u mcs13_prop[]; extern const int8u mcs5x10_mono[]; extern const int8u mcs5x11_mono[]; extern const int8u mcs6x10_mono[]; extern const int8u mcs6x11_mono[]; extern const int8u mcs7x12_mono_high[]; extern const int8u mcs7x12_mono_low[]; extern const int8u verdana12[]; extern const int8u verdana12_bold[]; extern const int8u verdana13[]; extern const int8u verdana13_bold[]; extern const int8u verdana14[]; extern const int8u verdana14_bold[]; extern const int8u verdana16[]; extern const int8u verdana16_bold[]; extern const int8u verdana17[]; extern const int8u verdana17_bold[]; extern const int8u verdana18[]; extern const int8u verdana18_bold[]; } #endif aggdraw-1.3.14/agg2/include/agg_font_cache_manager.h000066400000000000000000000330721417726601400222460ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_FONT_CACHE_MANAGER_INCLUDED #define AGG_FONT_CACHE_MANAGER_INCLUDED #include #include "agg_array.h" namespace agg { //---------------------------------------------------------glyph_data_type enum glyph_data_type { glyph_data_invalid = 0, glyph_data_mono = 1, glyph_data_gray8 = 2, glyph_data_outline = 3 }; //-------------------------------------------------------------glyph_cache struct glyph_cache { unsigned glyph_index; int8u* data; unsigned data_size; glyph_data_type data_type; rect bounds; double advance_x; double advance_y; }; //--------------------------------------------------------------font_cache class font_cache { public: enum { block_size = 16384-16 }; //-------------------------------------------------------------------- font_cache(const char* font_signature) : m_allocator(block_size), m_font_signature(0) { m_font_signature = (char*)m_allocator.allocate(strlen(font_signature) + 1); strcpy(m_font_signature, font_signature); memset(m_glyphs, 0, sizeof(m_glyphs)); } //-------------------------------------------------------------------- bool font_is(const char* font_signature) const { return strcmp(font_signature, m_font_signature) == 0; } //-------------------------------------------------------------------- const glyph_cache* find_glyph(unsigned glyph_code) const { unsigned msb = (glyph_code >> 8) & 0xFF; if(m_glyphs[msb]) { return m_glyphs[msb][glyph_code & 0xFF]; } return 0; } //-------------------------------------------------------------------- glyph_cache* cache_glyph(unsigned glyph_code, unsigned glyph_index, unsigned data_size, glyph_data_type data_type, const rect& bounds, double advance_x, double advance_y) { unsigned msb = (glyph_code >> 8) & 0xFF; if(m_glyphs[msb] == 0) { m_glyphs[msb] = (glyph_cache**)m_allocator.allocate(sizeof(glyph_cache*) * 256, sizeof(glyph_cache*)); memset(m_glyphs[msb], 0, sizeof(glyph_cache*) * 256); } unsigned lsb = glyph_code & 0xFF; if(m_glyphs[msb][lsb]) return 0; // Already exists, do not overwrite glyph_cache* glyph = (glyph_cache*)m_allocator.allocate(sizeof(glyph_cache), sizeof(int8u*)); glyph->glyph_index = glyph_index; glyph->data = m_allocator.allocate(data_size); glyph->data_size = data_size; glyph->data_type = data_type; glyph->bounds = bounds; glyph->advance_x = advance_x; glyph->advance_y = advance_y; return m_glyphs[msb][lsb] = glyph; } private: pod_allocator m_allocator; glyph_cache** m_glyphs[256]; char* m_font_signature; }; //---------------------------------------------------------font_cache_pool class font_cache_pool { public: //-------------------------------------------------------------------- ~font_cache_pool() { unsigned i; for(i = 0; i < m_num_fonts; ++i) { delete m_fonts[i]; } delete [] m_fonts; } //-------------------------------------------------------------------- font_cache_pool(unsigned max_fonts=32) : m_fonts(new font_cache* [max_fonts]), m_max_fonts(max_fonts), m_num_fonts(0), m_cur_font(0) {} //-------------------------------------------------------------------- void font(const char* font_signature, bool reset_cache = false) { int idx = find_font(font_signature); if(idx >= 0) { if(reset_cache) { delete m_fonts[idx]; m_fonts[idx] = new font_cache(font_signature); } m_cur_font = m_fonts[idx]; } else { if(m_num_fonts >= m_max_fonts) { delete m_fonts[0]; memcpy(m_fonts, m_fonts + 1, (m_max_fonts - 1) * sizeof(font_cache*)); m_num_fonts = m_max_fonts - 1; } m_fonts[m_num_fonts] = new font_cache(font_signature); m_cur_font = m_fonts[m_num_fonts]; ++m_num_fonts; } } //-------------------------------------------------------------------- const font_cache* font() const { return m_cur_font; } //-------------------------------------------------------------------- const glyph_cache* find_glyph(unsigned glyph_code) const { if(m_cur_font) return m_cur_font->find_glyph(glyph_code); return 0; } //-------------------------------------------------------------------- glyph_cache* cache_glyph(unsigned glyph_code, unsigned glyph_index, unsigned data_size, glyph_data_type data_type, const rect& bounds, double advance_x, double advance_y) { if(m_cur_font) { return m_cur_font->cache_glyph(glyph_code, glyph_index, data_size, data_type, bounds, advance_x, advance_y); } return 0; } //-------------------------------------------------------------------- int find_font(const char* font_signature) { unsigned i; for(i = 0; i < m_num_fonts; i++) { if(m_fonts[i]->font_is(font_signature)) return int(i); } return -1; } private: font_cache** m_fonts; unsigned m_max_fonts; unsigned m_num_fonts; font_cache* m_cur_font; }; //------------------------------------------------------------------------ enum glyph_rendering { glyph_ren_native_mono, glyph_ren_native_gray8, glyph_ren_outline, glyph_ren_agg_mono, glyph_ren_agg_gray8 }; //------------------------------------------------------font_cache_manager template class font_cache_manager { public: typedef FontEngine font_engine_type; typedef font_cache_manager self_type; typedef typename font_engine_type::path_adaptor_type path_adaptor_type; typedef typename font_engine_type::gray8_adaptor_type gray8_adaptor_type; typedef typename gray8_adaptor_type::embedded_scanline gray8_scanline_type; typedef typename font_engine_type::mono_adaptor_type mono_adaptor_type; typedef typename mono_adaptor_type::embedded_scanline mono_scanline_type; //-------------------------------------------------------------------- font_cache_manager(font_engine_type& engine, unsigned max_fonts=32) : m_fonts(max_fonts), m_engine(engine), m_change_stamp(-1), m_prev_glyph(0), m_last_glyph(0) {} //-------------------------------------------------------------------- const glyph_cache* glyph(unsigned glyph_code) { synchronize(); const glyph_cache* gl = m_fonts.find_glyph(glyph_code); if(gl) { m_prev_glyph = m_last_glyph; return m_last_glyph = gl; } else { if(m_engine.prepare_glyph(glyph_code)) { m_prev_glyph = m_last_glyph; m_last_glyph = m_fonts.cache_glyph(glyph_code, m_engine.glyph_index(), m_engine.data_size(), m_engine.data_type(), m_engine.bounds(), m_engine.advance_x(), m_engine.advance_y()); m_engine.write_glyph_to(m_last_glyph->data); return m_last_glyph; } } return 0; } //-------------------------------------------------------------------- void init_embedded_adaptors(const glyph_cache* gl, double x, double y) { if(gl) { switch(gl->data_type) { case glyph_data_mono: m_mono_adaptor.init(gl->data, gl->data_size, x, y); break; case glyph_data_gray8: m_gray8_adaptor.init(gl->data, gl->data_size, x, y); break; case glyph_data_outline: m_path_adaptor.init(gl->data, gl->data_size, x, y); break; } } } //-------------------------------------------------------------------- path_adaptor_type& path_adaptor() { return m_path_adaptor; } gray8_adaptor_type& gray8_adaptor() { return m_gray8_adaptor; } gray8_scanline_type& gray8_scanline() { return m_gray8_scanline; } mono_adaptor_type& mono_adaptor() { return m_mono_adaptor; } mono_scanline_type& mono_scanline() { return m_mono_scanline; } //-------------------------------------------------------------------- const glyph_cache* perv_glyph() const { return m_prev_glyph; } const glyph_cache* last_glyph() const { return m_last_glyph; } //-------------------------------------------------------------------- bool add_kerning(double* x, double* y) { if(m_prev_glyph && m_last_glyph) { return m_engine.add_kerning(m_prev_glyph->glyph_index, m_last_glyph->glyph_index, x, y); } return false; } //-------------------------------------------------------------------- void precache(unsigned from, unsigned to) { for(; from <= to; ++from) glyph(from); } //-------------------------------------------------------------------- void reset_cache() { m_fonts.font(m_engine.font_signature(), true); m_change_stamp = m_engine.change_stamp(); m_prev_glyph = m_last_glyph = 0; } private: //-------------------------------------------------------------------- font_cache_manager(const self_type&); const self_type& operator = (const self_type&); //-------------------------------------------------------------------- void synchronize() { if(m_change_stamp != m_engine.change_stamp()) { m_fonts.font(m_engine.font_signature()); m_change_stamp = m_engine.change_stamp(); m_prev_glyph = m_last_glyph = 0; } } font_cache_pool m_fonts; font_engine_type& m_engine; int m_change_stamp; double m_dx; double m_dy; const glyph_cache* m_prev_glyph; const glyph_cache* m_last_glyph; path_adaptor_type m_path_adaptor; gray8_adaptor_type m_gray8_adaptor; gray8_scanline_type m_gray8_scanline; mono_adaptor_type m_mono_adaptor; mono_scanline_type m_mono_scanline; }; } #endif aggdraw-1.3.14/agg2/include/agg_gamma_functions.h000066400000000000000000000062641417726601400216400ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_GAMMA_FUNCTIONS_INCLUDED #define AGG_GAMMA_FUNCTIONS_INCLUDED #include #include "agg_basics.h" namespace agg { //===============================================================gamma_none struct gamma_none { double operator()(double x) const { return x; } }; //==============================================================gamma_power class gamma_power { public: gamma_power() : m_gamma(1.0) {} gamma_power(double g) : m_gamma(g) {} void gamma(double g) { m_gamma = g; } double gamma() const { return m_gamma; } double operator() (double x) const { return pow(x, m_gamma); } private: double m_gamma; }; //==========================================================gamma_threshold class gamma_threshold { public: gamma_threshold() : m_threshold(0.5) {} gamma_threshold(double t) : m_threshold(t) {} void threshold(double t) { m_threshold = t; } double threshold() const { return m_threshold; } double operator() (double x) const { return (x < m_threshold) ? 0.0 : 1.0; } private: double m_threshold; }; //============================================================gamma_linear class gamma_linear { public: gamma_linear() : m_start(0.0), m_end(1.0) {} gamma_linear(double s, double e) : m_start(s), m_end(e) {} void set(double s, double e) { m_start = s; m_end = e; } void start(double s) { m_start = s; } void end(double e) { m_end = e; } double start() const { return m_start; } double end() const { return m_end; } double operator() (double x) const { if(x < m_start) return 0.0; if(x > m_end) return 1.0; return (x - m_start) / (m_end - m_start); } private: double m_start; double m_end; }; //==========================================================gamma_multiply class gamma_multiply { public: gamma_multiply() : m_mul(1.0) {} gamma_multiply(double v) : m_mul(v) {} void value(double v) { m_mul = v; } double value() const { return m_mul; } double operator() (double x) const { double y = x * m_mul; if(y > 1.0) y = 1.0; return y; } private: double m_mul; }; } #endif aggdraw-1.3.14/agg2/include/agg_gamma_lut.h000066400000000000000000000057631417726601400204370ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_GAMMA_LUT_INCLUDED #define AGG_GAMMA_LUT_INCLUDED #include #include "agg_basics.h" namespace agg { template class gamma_lut { public: enum { gamma_shift = GammaShift, gamma_size = 1 << gamma_shift, gamma_mask = gamma_size - 1 }; enum { hi_res_shift = HiResShift, hi_res_size = 1 << hi_res_shift, hi_res_mask = hi_res_size - 1 }; ~gamma_lut() { delete [] m_inv_gamma; delete [] m_dir_gamma; } gamma_lut() : m_gamma(1.0), m_dir_gamma(new HiResT[gamma_size]), m_inv_gamma(new LoResT[hi_res_size]) { unsigned i; for(i = 0; i < gamma_size; i++) { m_dir_gamma[i] = HiResT(i << (hi_res_shift - gamma_shift)); } for(i = 0; i < hi_res_size; i++) { m_inv_gamma[i] = LoResT(i >> (hi_res_shift - gamma_shift)); } } gamma_lut(double g) : m_gamma(1.0), m_dir_gamma(new HiResT[gamma_size]), m_inv_gamma(new LoResT[hi_res_size]) { gamma(g); } void gamma(double g) { m_gamma = g; unsigned i; for(i = 0; i < gamma_size; i++) { m_dir_gamma[i] = (HiResT)(pow(double(i) / double(gamma_mask), m_gamma) * double(hi_res_mask) + 0.5); } double inv_g = 1.0 / g; for(i = 0; i < hi_res_size; i++) { m_inv_gamma[i] = (LoResT)(pow(double(i) / double(hi_res_mask), inv_g) * double(gamma_mask) + 0.5); } } double gamma() const { return m_gamma; } HiResT dir(LoResT v) const { return m_dir_gamma[unsigned(v)]; } LoResT inv(HiResT v) const { return m_inv_gamma[unsigned(v)]; } private: double m_gamma; HiResT* m_dir_gamma; LoResT* m_inv_gamma; }; } #endif aggdraw-1.3.14/agg2/include/agg_glyph_raster_bin.h000066400000000000000000000114171417726601400220150ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_GLYPH_RASTER_BIN_INCLUDED #define AGG_GLYPH_RASTER_BIN_INCLUDED #include #include "agg_basics.h" namespace agg { //========================================================glyph_raster_bin template class glyph_raster_bin { public: typedef ColorT color_type; //-------------------------------------------------------------------- struct glyph_rect { int x1,y1,x2,y2; double dx, dy; }; //-------------------------------------------------------------------- glyph_raster_bin(const int8u* font) : m_font(font), m_big_endian(false) { int t = 1; if(*(char*)&t == 0) m_big_endian = true; memset(m_span, 0, sizeof(m_span)); } //-------------------------------------------------------------------- const int8u* font() const { return m_font; } void font(const int8u* f) { m_font = f; } //-------------------------------------------------------------------- double height() const { return m_font[0]; } double base_line() const { return m_font[1]; } //-------------------------------------------------------------------- template double width(const CharT* str) const { unsigned start_char = m_font[2]; unsigned num_chars = m_font[3]; unsigned w = 0; while(*str) { unsigned glyph = *str; const int8u* bits = m_font + 4 + num_chars * 2 + value(m_font + 4 + (glyph - start_char) * 2); w += *bits; ++str; } return w; } //-------------------------------------------------------------------- void prepare(glyph_rect* r, double x, double y, unsigned glyph, bool flip) { unsigned start_char = m_font[2]; unsigned num_chars = m_font[3]; m_bits = m_font + 4 + num_chars * 2 + value(m_font + 4 + (glyph - start_char) * 2); m_glyph_width = *m_bits++; m_glyph_byte_width = (m_glyph_width + 7) >> 3; r->x1 = int(x); r->x2 = r->x1 + m_glyph_width - 1; if(flip) { r->y1 = int(y) - m_font[0] + m_font[1]; r->y2 = r->y1 + m_font[0] - 1; } else { r->y1 = int(y) - m_font[1] + 1; r->y2 = r->y1 + m_font[0] - 1; } r->dx = m_glyph_width; r->dy = 0; } //-------------------------------------------------------------------- const cover_type* span(unsigned i) { i = m_font[0] - i - 1; const int8u* bits = m_bits + i * m_glyph_byte_width; unsigned j; unsigned val = *bits; unsigned nb = 0; for(j = 0; j < m_glyph_width; ++j) { m_span[j] = (cover_type)((val & 0x80) ? cover_full : cover_none); val <<= 1; if(++nb >= 8) { val = *++bits; nb = 0; } } return m_span; } private: //-------------------------------------------------------------------- int16u value(const int8u* p) const { int16u v; if(m_big_endian) { *(int8u*)&v = p[1]; *((int8u*)&v + 1) = p[0]; } else { *(int8u*)&v = p[0]; *((int8u*)&v + 1) = p[1]; } return v; } //-------------------------------------------------------------------- const int8u* m_font; bool m_big_endian; cover_type m_span[32]; const int8u* m_bits; unsigned m_glyph_width; unsigned m_glyph_byte_width; }; } #endif aggdraw-1.3.14/agg2/include/agg_gray8.h000066400000000000000000000062241417726601400175140ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // color type gray8 // //---------------------------------------------------------------------------- #ifndef AGG_GRAY8_INCLUDED #define AGG_GRAY8_INCLUDED #include "agg_basics.h" #include "agg_color_rgba.h" #include "agg_color_rgba8.h" namespace agg { //===================================================================gray8 struct gray8 { int8u v; int8u a; //-------------------------------------------------------------------- gray8() {} //-------------------------------------------------------------------- gray8(unsigned v_, unsigned a_=255) : v(int8u(v_)), a(int8u(a_)) {} //-------------------------------------------------------------------- gray8(const rgba& c) : v(int8u((0.299*c.r + 0.587*c.g + 0.114*c.b) * 255.0 + 0.5)), a(int8u(c.a*255.0)) {} //-------------------------------------------------------------------- gray8(const rgba8& c) : v((c.r*77 + c.g*150 + c.b*29) >> 8), a(c.a) {} //-------------------------------------------------------------------- void clear() { v = a = 0; } //-------------------------------------------------------------------- const gray8& transparent() { a = 0; return *this; } //-------------------------------------------------------------------- void opacity(double a_) { if(a_ < 0.0) a_ = 0.0; if(a_ > 1.0) a_ = 1.0; a = int8u(a_ * 255.0); } //-------------------------------------------------------------------- double opacity() const { return double(a) / 255.0; } //-------------------------------------------------------------------- gray8 gradient(gray8 c, double k) const { gray8 ret; int ik = int(k * 256); ret.v = int8u(int(v) + (((int(c.v) - int(v)) * ik) >> 8)); ret.a = int8u(int(a) + (((int(c.a) - int(a)) * ik) >> 8)); return ret; } //-------------------------------------------------------------------- gray8 pre() const { return gray8((v*a) >> 8, a); } //-------------------------------------------------------------------- static gray8 no_color() { return gray8(0,0); } }; } #endif aggdraw-1.3.14/agg2/include/agg_gsv_text.h000066400000000000000000000076051417726601400203310ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Class gsv_text // //---------------------------------------------------------------------------- #ifndef AGG_GSV_TEXT_INCLUDED #define AGG_GSV_TEXT_INCLUDED #include "agg_basics.h" #include "agg_conv_stroke.h" #include "agg_conv_transform.h" namespace agg { //---------------------------------------------------------------gsv_text // // See Implementation agg_gsv_text.cpp // class gsv_text { enum status { initial, next_char, start_glyph, glyph }; public: ~gsv_text(); gsv_text(); void font(const void* font); void flip(bool flip_y) { m_flip = flip_y; } void load_font(const char* file); void size(double height, double width=0.0); void space(double space); void line_space(double line_space); void start_point(double x, double y); void text(const char* text); void rewind(unsigned id); unsigned vertex(double* x, double* y); private: // not supposed to be copied gsv_text(const gsv_text&); const gsv_text& operator = (const gsv_text&); int16u value(const int8u* p) const { int16u v; if(m_big_endian) { *(int8u*)&v = p[1]; *((int8u*)&v + 1) = p[0]; } else { *(int8u*)&v = p[0]; *((int8u*)&v + 1) = p[1]; } return v; } private: double m_x; double m_y; double m_start_x; double m_width; double m_height; double m_space; double m_line_space; char m_chr[2]; char* m_text; char* m_text_buf; unsigned m_buf_size; char* m_cur_chr; const void* m_font; char* m_loaded_font; status m_status; bool m_big_endian; bool m_flip; int8u* m_indices; int8* m_glyphs; int8* m_bglyph; int8* m_eglyph; double m_w; double m_h; }; //--------------------------------------------------------gsv_text_outline template class gsv_text_outline { public: gsv_text_outline(gsv_text& text, const Transformer& trans) : m_polyline(text), m_trans(m_polyline, trans) { } void width(double w) { m_polyline.width(w); } void transformer(const Transformer* trans) { m_trans->transformer(trans); } void rewind(unsigned id) { m_trans.rewind(id); m_polyline.line_join(vcgen_stroke::round_join); m_polyline.line_cap(vcgen_stroke::round_cap); } unsigned vertex(double* x, double* y) { return m_trans.vertex(x, y); } private: conv_stroke m_polyline; conv_transform, Transformer> m_trans; }; } #endif aggdraw-1.3.14/agg2/include/agg_image_filters.h000066400000000000000000000236021417726601400212730ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Image transformation filters, // Filtering classes (image_filter_base, image_filter), // Basic filter shape classes: // image_filter_bilinear, // image_filter_bicubic, // image_filter_spline16, // image_filter_spline36, // image_filter_sinc64, // image_filter_sinc144, // image_filter_sinc196, // image_filter_sinc256 // //---------------------------------------------------------------------------- #ifndef AGG_IMAGE_FILTERS_INCLUDED #define AGG_IMAGE_FILTERS_INCLUDED #include #include "agg_basics.h" namespace agg { // See Implementation agg_image_filters.cpp enum { image_filter_shift = 14, //----image_filter_shift image_filter_size = 1 << image_filter_shift, //----image_filter_size image_filter_mask = image_filter_size - 1, //----image_filter_mask image_subpixel_shift = 8, //----image_subpixel_shift image_subpixel_size = 1 << image_subpixel_shift, //----image_subpixel_size image_subpixel_mask = image_subpixel_size - 1 //----image_subpixel_mask }; //-----------------------------------------------------image_filter_base class image_filter_base { public: ~image_filter_base(); image_filter_base(unsigned dimension); unsigned dimension() const { return m_dimension; } int start() const { return m_start; } const double* weight_array_dbl() const { return m_weight_array_dbl; } const int* weight_array_int() const { return m_weight_array_int; } protected: void weight(unsigned idx, double val); double calc_x(unsigned idx) const; void normalize(); private: image_filter_base(const image_filter_base&); const image_filter_base& operator = (const image_filter_base&); unsigned m_dimension; int m_start; double* m_weight_array_dbl; int* m_weight_array_int; }; //--------------------------------------------------------image_filter template class image_filter : public image_filter_base { public: image_filter() : image_filter_base(FilterF::dimension()), m_filter_function() { unsigned i; unsigned dim = dimension() << image_subpixel_shift; for(i = 0; i < dim; i++) { weight(i, m_filter_function.calc_weight(calc_x(i))); } normalize(); } private: FilterF m_filter_function; }; //-----------------------------------------------image_filter_bilinear class image_filter_bilinear { public: static unsigned dimension() { return 2; } static double calc_weight(double x) { return (x <= 0.0) ? x + 1.0 : 1.0 - x; } }; //------------------------------------------------image_filter_bicubic class image_filter_bicubic { static double pow3(double x) { return (x <= 0.0) ? 0.0 : x * x * x; } public: static unsigned dimension() { return 4; } static double calc_weight(double x) { return (1.0/6.0) * (pow3(x + 2) - 4 * pow3(x + 1) + 6 * pow3(x) - 4 * pow3(x - 1)); } }; //----------------------------------------------image_filter_spline16 class image_filter_spline16 { public: static unsigned dimension() { return 4; } static double calc_weight(double x) { if(x < 0.0) x = -x; if(x < 1.0) { return ((x - 9.0/5.0 ) * x - 1.0/5.0 ) * x + 1.0; } return ((-1.0/3.0 * (x-1) + 4.0/5.0) * (x-1) - 7.0/15.0 ) * (x-1); } }; //---------------------------------------------image_filter_spline36 class image_filter_spline36 { public: static unsigned dimension() { return 6; } static double calc_weight(double x) { if(x < 0.0) x = -x; if(x < 1.0) { return ((13.0/11.0 * x - 453.0/209.0) * x - 3.0/209.0) * x + 1.0; } if(x < 2.0) { return ((-6.0/11.0 * (x-1) + 270.0/209.0) * (x-1) - 156.0/ 209.0) * (x-1); } return ((1.0/11.0 * (x-2) - 45.0/209.0) * (x-2) + 26.0/209.0) * (x-2); } }; //-----------------------------------------------image_filter_sinc36 class image_filter_sinc36 { public: static unsigned dimension() { return 6; } static double calc_weight(double x) { if(x == 0.0) return 1.0; x *= pi; double x3 = x * (1.0/3.0); return (sin(x) / x) * (sin(x3) / x3); } }; //------------------------------------------------image_filter_sinc64 class image_filter_sinc64 { public: static unsigned dimension() { return 8; } static double calc_weight(double x) { if(x == 0.0) return 1.0; x *= pi; double x4 = x * 0.25; return (sin(x) / x) * (sin(x4) / x4); } }; //-----------------------------------------------image_filter_sinc100 class image_filter_sinc100 { public: static unsigned dimension() { return 10; } static double calc_weight(double x) { if(x == 0.0) return 1.0; x *= pi; double x5 = x * 0.2; return (sin(x) / x) * (sin(x5) / x5); } }; //-----------------------------------------------image_filter_sinc144 class image_filter_sinc144 { public: static unsigned dimension() { return 12; } static double calc_weight(double x) { if(x == 0.0) return 1.0; x *= pi; double x6 = x * (1.0/6.0); return (sin(x) / x) * (sin(x6) / x6); } }; //-----------------------------------------------image_filter_sinc196 class image_filter_sinc196 { public: static unsigned dimension() { return 14; } static double calc_weight(double x) { if(x == 0.0) return 1.0; x *= pi; double x7 = x * (1.0/7.0); return (sin(x) / x) * (sin(x7) / x7); } }; //-----------------------------------------------image_filter_sinc256 class image_filter_sinc256 { public: static unsigned dimension() { return 16; } static double calc_weight(double x) { if(x == 0.0) return 1.0; x *= pi; double x8 = x * 0.125; return (sin(x) / x) * (sin(x8) / x8); } }; //--------------------------------------------image_filter_blackman36 class image_filter_blackman36 { public: static unsigned dimension() { return 6; } static double calc_weight(double x) { if(x == 0.0) return 1.0; x *= pi; double x3 = x * (1.0/3.0); return (sin(x) / x) * (0.42 + 0.5*cos(x3) + 0.08*cos(2*x3)); } }; //--------------------------------------------image_filter_blackman64 class image_filter_blackman64 { public: static unsigned dimension() { return 8; } static double calc_weight(double x) { if(x == 0.0) return 1.0; x *= pi; double x4 = x * 0.25; return (sin(x) / x) * (0.42 + 0.5*cos(x4) + 0.08*cos(2*x4)); } }; //-------------------------------------------image_filter_blackman100 class image_filter_blackman100 { public: static unsigned dimension() { return 10; } static double calc_weight(double x) { if(x == 0.0) return 1.0; x *= pi; double x5 = x * 0.2; return (sin(x) / x) * (0.42 + 0.5*cos(x5) + 0.08*cos(2*x5)); } }; //-------------------------------------------image_filter_blackman144 class image_filter_blackman144 { public: static unsigned dimension() { return 12; } static double calc_weight(double x) { if(x == 0.0) return 1.0; x *= pi; double x6 = x * (1.0/6.0); return (sin(x) / x) * (0.42 + 0.5*cos(x6) + 0.08*cos(2*x6)); } }; //-------------------------------------------image_filter_blackman196 class image_filter_blackman196 { public: static unsigned dimension() { return 14; } static double calc_weight(double x) { if(x == 0.0) return 1.0; x *= pi; double x7 = x * (1.0/7.0); return (sin(x) / x) * (0.42 + 0.5*cos(x7) + 0.08*cos(2*x7)); } }; //-------------------------------------------image_filter_blackman256 class image_filter_blackman256 { public: static unsigned dimension() { return 16; } static double calc_weight(double x) { if(x == 0.0) return 1.0; x *= pi; double x8 = x * 0.125; return (sin(x) / x) * (0.42 + 0.5*cos(x8) + 0.08*cos(2*x8)); } }; } #endif aggdraw-1.3.14/agg2/include/agg_line_aa_basics.h000066400000000000000000000105441417726601400213760ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_LINE_AA_BASICS_INCLUDED #define AGG_LINE_AA_BASICS_INCLUDED #include #include "agg_basics.h" namespace agg { // See Implementation agg_line_aa_basics.cpp //------------------------------------------------------------------------- enum { line_subpixel_shift = 8, //----line_subpixel_shift line_subpixel_size = 1 << line_subpixel_shift, //----line_subpixel_size line_subpixel_mask = line_subpixel_size - 1 //----line_subpixel_mask }; //------------------------------------------------------------------------- enum { line_mr_subpixel_shift = 4, //----line_mr_subpixel_shift line_mr_subpixel_size = 1 << line_mr_subpixel_shift, //----line_mr_subpixel_size line_mr_subpixel_mask = line_mr_subpixel_size - 1 //----line_mr_subpixel_mask }; //------------------------------------------------------------------line_mr inline int line_mr(int x) { return x >> (line_subpixel_shift - line_mr_subpixel_shift); } //-------------------------------------------------------------------line_hr inline int line_hr(int x) { return x << (line_subpixel_shift - line_mr_subpixel_shift); } //---------------------------------------------------------------line_dbl_hr inline int line_dbl_hr(int x) { return x << line_subpixel_shift; } //---------------------------------------------------------------line_coord inline int line_coord(double x) { return int(x * line_subpixel_size); } //==========================================================line_parameters struct line_parameters { //--------------------------------------------------------------------- line_parameters() {} line_parameters(int x1_, int y1_, int x2_, int y2_, int len_) : x1(x1_), y1(y1_), x2(x2_), y2(y2_), dx(abs(x2_ - x1_)), dy(abs(y2_ - y1_)), sx((x2_ > x1_) ? 1 : -1), sy((y2_ > y1_) ? 1 : -1), vertical(dy >= dx), inc(vertical ? sy : sx), len(len_), octant((sy & 4) | (sx & 2) | int(vertical)) { } //--------------------------------------------------------------------- unsigned orthogonal_quadrant() const { return s_orthogonal_quadrant[octant]; } unsigned diagonal_quadrant() const { return s_diagonal_quadrant[octant]; } //--------------------------------------------------------------------- bool same_orthogonal_quadrant(const line_parameters& lp) const { return s_orthogonal_quadrant[octant] == s_orthogonal_quadrant[lp.octant]; } //--------------------------------------------------------------------- bool same_diagonal_quadrant(const line_parameters& lp) const { return s_diagonal_quadrant[octant] == s_diagonal_quadrant[lp.octant]; } //--------------------------------------------------------------------- int x1, y1, x2, y2, dx, dy, sx, sy; bool vertical; int inc; int len; int octant; //--------------------------------------------------------------------- static int8u s_orthogonal_quadrant[8]; static int8u s_diagonal_quadrant[8]; }; // See Implementation agg_line_aa_basics.cpp //----------------------------------------------------------------bisectrix void bisectrix(const line_parameters& l1, const line_parameters& l2, int* x, int* y); } #endif aggdraw-1.3.14/agg2/include/agg_math.h000066400000000000000000000175011417726601400174130ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_MATH_INCLUDED #define AGG_MATH_INCLUDED #include #include "agg_basics.h" namespace agg { const double intersection_epsilon = 1.0e-8; //------------------------------------------------------calc_point_location inline double calc_point_location(double x1, double y1, double x2, double y2, double x, double y) { return (x - x2) * (y2 - y1) - (y - y2) * (x2 - x1); } //--------------------------------------------------------point_in_triangle inline bool point_in_triangle(double x1, double y1, double x2, double y2, double x3, double y3, double x, double y) { bool cp1 = calc_point_location(x1, y1, x2, y2, x, y) < 0.0; bool cp2 = calc_point_location(x2, y2, x3, y3, x, y) < 0.0; bool cp3 = calc_point_location(x3, y3, x1, y1, x, y) < 0.0; return cp1 == cp2 && cp2 == cp3 && cp3 == cp1; } //-----------------------------------------------------------calc_distance inline double calc_distance(double x1, double y1, double x2, double y2) { double dx = x2-x1; double dy = y2-y1; return sqrt(dx * dx + dy * dy); } //------------------------------------------------calc_point_line_distance inline double calc_point_line_distance(double x1, double y1, double x2, double y2, double x, double y) { double dx = x2-x1; double dy = y2-y1; return ((x - x2) * dy - (y - y2) * dx) / sqrt(dx * dx + dy * dy); } //-------------------------------------------------------calc_intersection inline bool calc_intersection(double ax, double ay, double bx, double by, double cx, double cy, double dx, double dy, double* x, double* y) { double num = (ay-cy) * (dx-cx) - (ax-cx) * (dy-cy); double den = (bx-ax) * (dy-cy) - (by-ay) * (dx-cx); if(fabs(den) < intersection_epsilon) return false; double r = num / den; *x = ax + r * (bx-ax); *y = ay + r * (by-ay); return true; } //--------------------------------------------------------calc_orthogonal inline void calc_orthogonal(double thickness, double x1, double y1, double x2, double y2, double* x, double* y) { double dx = x2 - x1; double dy = y2 - y1; double d = sqrt(dx*dx + dy*dy); *x = thickness * dy / d; *y = thickness * dx / d; } //--------------------------------------------------------dilate_triangle inline void dilate_triangle(double x1, double y1, double x2, double y2, double x3, double y3, double *x, double* y, double d) { double dx1=0.0; double dy1=0.0; double dx2=0.0; double dy2=0.0; double dx3=0.0; double dy3=0.0; double loc = calc_point_location(x1, y1, x2, y2, x3, y3); if(fabs(loc) > intersection_epsilon) { if(calc_point_location(x1, y1, x2, y2, x3, y3) > 0.0) { d = -d; } calc_orthogonal(d, x1, y1, x2, y2, &dx1, &dy1); calc_orthogonal(d, x2, y2, x3, y3, &dx2, &dy2); calc_orthogonal(d, x3, y3, x1, y1, &dx3, &dy3); } *x++ = x1 + dx1; *y++ = y1 - dy1; *x++ = x2 + dx1; *y++ = y2 - dy1; *x++ = x2 + dx2; *y++ = y2 - dy2; *x++ = x3 + dx2; *y++ = y3 - dy2; *x++ = x3 + dx3; *y++ = y3 - dy3; *x++ = x1 + dx3; *y++ = y1 - dy3; } //-------------------------------------------------------calc_polygon_area template double calc_polygon_area(const Storage& st) { unsigned i; double sum = 0.0; double x = st[0].x; double y = st[0].y; double xs = x; double ys = y; for(i = 1; i < st.size(); i++) { const typename Storage::value_type& v = st[i]; sum += x * v.y - y * v.x; x = v.x; y = v.y; } return (sum + x * ys - y * xs) * 0.5; } //------------------------------------------------------------------------ // Tables for fast sqrt extern int16u g_sqrt_table[1024]; extern int8 g_elder_bit_table[256]; //---------------------------------------------------------------fast_sqrt //Fast integer Sqrt - really fast: no cycles, divisions or multiplications #if defined(_MSC_VER) #pragma warning(push) #pragma warning(disable : 4035) //Disable warning "no return value" #endif inline unsigned fast_sqrt(unsigned val) { #if defined(_M_IX86) && defined(_MSC_VER) && !defined(AGG_NO_ASM) //For Ix86 family processors this assembler code is used. //The key command here is bsr - determination the number of the most //significant bit of the value. For other processors //(and maybe compilers) the pure C "#else" section is used. __asm { mov ebx, val mov edx, 11 bsr ecx, ebx sub ecx, 9 jle less_than_9_bits shr ecx, 1 adc ecx, 0 sub edx, ecx shl ecx, 1 shr ebx, cl less_than_9_bits: xor eax, eax mov ax, g_sqrt_table[ebx*2] mov ecx, edx shr eax, cl } #else //This code is actually pure C and portable to most //arcitectures including 64bit ones. unsigned t = val; int bit=0; unsigned shift = 11; //The following piece of code is just an emulation of the //Ix86 assembler command "bsr" (see above). However on old //Intels (like Intel MMX 233MHz) this code is about twice //faster (sic!) then just one "bsr". On PIII and PIV the //bsr is optimized quite well. bit = t >> 24; if(bit) { bit = g_elder_bit_table[bit] + 24; } else { bit = (t >> 16) & 0xFF; if(bit) { bit = g_elder_bit_table[bit] + 16; } else { bit = (t >> 8) & 0xFF; if(bit) { bit = g_elder_bit_table[bit] + 8; } else { bit = g_elder_bit_table[t]; } } } //This is calculation sqrt itself. bit -= 9; if(bit > 0) { bit = (bit >> 1) + (bit & 1); shift -= bit; val >>= (bit << 1); } return g_sqrt_table[val] >> shift; #endif } #if defined(_MSC_VER) #pragma warning(pop) #endif } #endif aggdraw-1.3.14/agg2/include/agg_path_storage.h000066400000000000000000000301031417726601400211330ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_PATH_STORAGE_INCLUDED #define AGG_PATH_STORAGE_INCLUDED #include "agg_basics.h" namespace agg { //------------------------------------------------------------path_storage // A container to store vertices with their flags. // A path consists of a number of contours separated with "move_to" // commands. The path storage can keep and maintain more than one // path. // To navigate to the beginning of a particular path, use rewind(path_id); // Where path_id is what start_new_path() returns. So, when you call // start_new_path() you need to store its return value somewhere else // to navigate to the path afterwards. // // See Implementation: agg_path_storage.cpp // See also: vertex_source concept //------------------------------------------------------------------------ class path_storage { // Allocation parameters enum { block_shift = 8, block_size = 1 << block_shift, block_mask = block_size - 1, block_pool = 256 }; public: //-------------------------------------------------------------------- class const_iterator { void vertex() { if(m_vertex_idx < m_path->total_vertices()) { m_vertex.cmd = m_path->vertex(m_vertex_idx, &m_vertex.x, &m_vertex.y); } else { m_vertex.cmd = path_cmd_stop; m_vertex.x = m_vertex.y = 0.0; } } public: const_iterator() {} const_iterator(unsigned cmd) { m_vertex.cmd = cmd; } const_iterator(const const_iterator& i) : m_path(i.m_path), m_vertex_idx(i.m_vertex_idx), m_vertex(i.m_vertex) { } const_iterator(const path_storage& p, unsigned id) : m_path(&p), m_vertex_idx(id) { vertex(); } const_iterator& operator++() { ++m_vertex_idx; vertex(); return *this; } const vertex_type& operator*() const { return m_vertex; } const vertex_type* operator->() const { return &m_vertex; } bool operator != (const const_iterator& i) { return m_vertex.cmd != i.m_vertex.cmd; } private: const path_storage* m_path; unsigned m_vertex_idx; vertex_type m_vertex; }; ~path_storage(); path_storage(); path_storage(const path_storage& ps); void remove_all(); unsigned last_vertex(double* x, double* y) const; unsigned prev_vertex(double* x, double* y) const; void rel_to_abs(double* x, double* y) const; void move_to(double x, double y); void move_rel(double dx, double dy); void line_to(double x, double y); void line_rel(double dx, double dy); void arc_to(double rx, double ry, double angle, bool large_arc_flag, bool sweep_flag, double x, double y); void arc_rel(double rx, double ry, double angle, bool large_arc_flag, bool sweep_flag, double dx, double dy); void curve3(double x_ctrl, double y_ctrl, double x_to, double y_to); void curve3_rel(double dx_ctrl, double dy_ctrl, double dx_to, double dy_to); void curve3(double x_to, double y_to); void curve3_rel(double dx_to, double dy_to); void curve4(double x_ctrl1, double y_ctrl1, double x_ctrl2, double y_ctrl2, double x_to, double y_to); void curve4_rel(double dx_ctrl1, double dy_ctrl1, double dx_ctrl2, double dy_ctrl2, double dx_to, double dy_to); void curve4(double x_ctrl2, double y_ctrl2, double x_to, double y_to); void curve4_rel(double x_ctrl2, double y_ctrl2, double x_to, double y_to); void end_poly(unsigned flags = path_flags_close); void close_polygon(unsigned flags = path_flags_none) { end_poly(path_flags_close | flags); } void add_poly(const double* vertices, unsigned num, bool solid_path = false, unsigned end_flags = path_flags_none); void add_vertices(const double* vertices, unsigned num) { add_poly(vertices, num, path_flags_none); } template void add_path(VertexSource& vs, unsigned path_id = 0, bool solid_path = true) { double x, y; unsigned cmd; vs.rewind(path_id); while(!is_stop(cmd = vs.vertex(&x, &y))) { if(is_move_to(cmd) && solid_path && m_total_vertices) { cmd = path_cmd_line_to; } add_vertex(x, y, cmd); } } unsigned start_new_path(); void copy_from(const path_storage& ps); const path_storage& operator = (const path_storage& ps) { copy_from(ps); return *this; } unsigned total_vertices() const { return m_total_vertices; } unsigned vertex(unsigned idx, double* x, double* y) const { unsigned nb = idx >> block_shift; const double* pv = m_coord_blocks[nb] + ((idx & block_mask) << 1); *x = *pv++; *y = *pv; return m_cmd_blocks[nb][idx & block_mask]; } unsigned command(unsigned idx) const { return m_cmd_blocks[idx >> block_shift][idx & block_mask]; } void rewind(unsigned path_id); unsigned vertex(double* x, double* y); const_iterator begin(unsigned id) const { return const_iterator(*this, id); } const_iterator begin() const { return const_iterator(*this, 0); } const_iterator end() const { return const_iterator(path_cmd_stop); } // Arrange the orientation of all the polygons. After calling this // method all the polygons will have the same orientation // determined by the new_orientation flag, i.e., // path_flags_cw or path_flags_ccw unsigned arrange_orientations(unsigned path_id, path_flags_e new_orientation); void arrange_orientations_all_paths(path_flags_e new_orientation); // Flip all the vertices horizontally or vertically void flip_x(double x1, double x2); void flip_y(double y1, double y2); // This function adds a vertex with its flags directly. Since there's no // checking for errors, keeping proper path integrity is the responsibility // of the caller. It can be said the function is "not very public". void add_vertex(double x, double y, unsigned cmd); // Allows you to modify vertex coordinates. The caller must know // the index of the vertex. void modify_vertex(unsigned idx, double x, double y) { double* pv = m_coord_blocks[idx >> block_shift] + ((idx & block_mask) << 1); *pv++ = x; *pv = y; } // Allows you to modify vertex command. The caller must know // the index of the vertex. void modify_command(unsigned idx, unsigned cmd) { m_cmd_blocks[idx >> block_shift][idx & block_mask] = (unsigned char)cmd; } private: void allocate_block(unsigned nb); unsigned char* storage_ptrs(double** xy_ptr); unsigned perceive_polygon_orientation(unsigned idx, double xs, double ys, unsigned* orientation); void reverse_polygon(unsigned start, unsigned end); private: unsigned m_total_vertices; unsigned m_total_blocks; unsigned m_max_blocks; double** m_coord_blocks; unsigned char** m_cmd_blocks; unsigned m_iterator; }; //------------------------------------------------------------------------ inline unsigned path_storage::vertex(double* x, double* y) { if(m_iterator >= m_total_vertices) return path_cmd_stop; return vertex(m_iterator++, x, y); } //------------------------------------------------------------------------ inline unsigned path_storage::prev_vertex(double* x, double* y) const { if(m_total_vertices > 1) { return vertex(m_total_vertices - 2, x, y); } return path_cmd_stop; } //------------------------------------------------------------------------ inline unsigned path_storage::last_vertex(double* x, double* y) const { if(m_total_vertices) { return vertex(m_total_vertices - 1, x, y); } return path_cmd_stop; } //------------------------------------------------------------------------ inline void path_storage::rel_to_abs(double* x, double* y) const { if(m_total_vertices) { double x2; double y2; if(is_vertex(vertex(m_total_vertices - 1, &x2, &y2))) { *x += x2; *y += y2; } } } //------------------------------------------------------------------------ inline unsigned char* path_storage::storage_ptrs(double** xy_ptr) { unsigned nb = m_total_vertices >> block_shift; if(nb >= m_total_blocks) { allocate_block(nb); } *xy_ptr = m_coord_blocks[nb] + ((m_total_vertices & block_mask) << 1); return m_cmd_blocks[nb] + (m_total_vertices & block_mask); } //------------------------------------------------------------------------ inline void path_storage::add_vertex(double x, double y, unsigned cmd) { double* coord_ptr = 0; unsigned char* cmd_ptr = storage_ptrs(&coord_ptr); *cmd_ptr = (unsigned char)cmd; *coord_ptr++ = x; *coord_ptr = y; m_total_vertices++; } //------------------------------------------------------------------------ inline void path_storage::move_to(double x, double y) { add_vertex(x, y, path_cmd_move_to); } //------------------------------------------------------------------------ inline void path_storage::move_rel(double dx, double dy) { rel_to_abs(&dx, &dy); add_vertex(dx, dy, path_cmd_move_to); } //------------------------------------------------------------------------ inline void path_storage::line_to(double x, double y) { add_vertex(x, y, path_cmd_line_to); } //------------------------------------------------------------------------ inline void path_storage::line_rel(double dx, double dy) { rel_to_abs(&dx, &dy); add_vertex(dx, dy, path_cmd_line_to); } } #endif aggdraw-1.3.14/agg2/include/agg_path_storage_integer.h000066400000000000000000000226301417726601400226560ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_PATH_STORAGE_INTEGER_INCLUDED #define AGG_PATH_STORAGE_INTEGER_INCLUDED #include #include "agg_array.h" namespace agg { //---------------------------------------------------------vertex_integer template struct vertex_integer { enum path_cmd { cmd_move_to = 0, cmd_line_to = 1, cmd_curve3 = 2, cmd_curve4 = 3 }; enum { coord_shift = CoordShift, coord_mult = 1 << coord_shift }; T x,y; vertex_integer() {} vertex_integer(T x_, T y_, unsigned flag) : x(((x_ << 1) & ~1) | (flag & 1)), y(((y_ << 1) & ~1) | (flag >> 1)) {} unsigned vertex(double* x_, double* y_, double dx=0, double dy=0) const { *x_ = dx + (double(x >> 1) / coord_mult); *y_ = dy + (double(y >> 1) / coord_mult); switch(((y & 1) << 1) | (x & 1)) { case cmd_move_to: return path_cmd_move_to; case cmd_line_to: return path_cmd_line_to; case cmd_curve3: return path_cmd_curve3; case cmd_curve4: return path_cmd_curve4; } return path_cmd_stop; } }; //---------------------------------------------------path_storage_integer template class path_storage_integer { public: typedef vertex_integer vertex_integer_type; //-------------------------------------------------------------------- path_storage_integer() : m_storage(), m_vertex_idx(0), m_closed(true) {} //-------------------------------------------------------------------- void remove_all() { m_storage.remove_all(); } //-------------------------------------------------------------------- void move_to(T x, T y) { m_storage.add(vertex_integer_type(x, y, vertex_integer_type::cmd_move_to)); } //-------------------------------------------------------------------- void line_to(T x, T y) { m_storage.add(vertex_integer_type(x, y, vertex_integer_type::cmd_line_to)); } //-------------------------------------------------------------------- void curve3(T x_ctrl, T y_ctrl, T x_to, T y_to) { m_storage.add(vertex_integer_type(x_ctrl, y_ctrl, vertex_integer_type::cmd_curve3)); m_storage.add(vertex_integer_type(x_to, y_to, vertex_integer_type::cmd_curve3)); } //-------------------------------------------------------------------- void curve4(T x_ctrl1, T y_ctrl1, T x_ctrl2, T y_ctrl2, T x_to, T y_to) { m_storage.add(vertex_integer_type(x_ctrl1, y_ctrl1, vertex_integer_type::cmd_curve4)); m_storage.add(vertex_integer_type(x_ctrl2, y_ctrl2, vertex_integer_type::cmd_curve4)); m_storage.add(vertex_integer_type(x_to, y_to, vertex_integer_type::cmd_curve4)); } //-------------------------------------------------------------------- void close_polygon() {} //-------------------------------------------------------------------- unsigned size() const { return m_storage.size(); } unsigned vertex(unsigned idx, T* x, T* y) const { const vertex_integer_type& v = m_storage[idx]; *x = v.x >> 1; *y = v.y >> 1; return ((v.y & 1) << 1) | (v.x & 1); } //-------------------------------------------------------------------- unsigned byte_size() const { return m_storage.size() * sizeof(vertex_integer_type); } void serialize(int8u* ptr) const { unsigned i; for(i = 0; i < m_storage.size(); i++) { memcpy(ptr, &m_storage[i], sizeof(vertex_integer_type)); ptr += sizeof(vertex_integer_type); } } //-------------------------------------------------------------------- void rewind(unsigned) { m_vertex_idx = 0; m_closed = true; } //-------------------------------------------------------------------- unsigned vertex(double* x, double* y) { if(m_storage.size() < 2 || m_vertex_idx > m_storage.size()) { *x = 0; *y = 0; return path_cmd_stop; } if(m_vertex_idx == m_storage.size()) { *x = 0; *y = 0; ++m_vertex_idx; return path_cmd_end_poly | path_flags_close; } unsigned cmd = m_storage[m_vertex_idx].vertex(x, y); if(is_move_to(cmd) && !m_closed) { *x = 0; *y = 0; m_closed = true; return path_cmd_end_poly | path_flags_close; } m_closed = false; ++m_vertex_idx; return cmd; } //-------------------------------------------------------------------- rect_d bounding_rect() const { rect_d bounds(1e100, 1e100, -1e100, -1e100); if(m_storage.size() == 0) { bounds.x1 = bounds.x1 = bounds.x2 = bounds.y2 = 0.0; } else { unsigned i; for(i = 0; i < m_storage.size(); i++) { double x, y; m_storage[i].vertex(&x, &y); if(x < bounds.x1) bounds.x1 = x; if(y < bounds.y1) bounds.y1 = y; if(x > bounds.x2) bounds.x2 = x; if(y > bounds.y2) bounds.y2 = y; } } return bounds; } private: pod_deque m_storage; unsigned m_vertex_idx; bool m_closed; }; //-----------------------------------------serialized_integer_path_adaptor template class serialized_integer_path_adaptor { public: typedef vertex_integer vertex_integer_type; //-------------------------------------------------------------------- serialized_integer_path_adaptor() : m_data(0), m_end(0), m_ptr(0), m_dx(0.0), m_dy(0.0), m_closed(true) {} //-------------------------------------------------------------------- serialized_integer_path_adaptor(const int8u* data, unsigned size, double dx, double dy) : m_data(data), m_end(data + size), m_ptr(data), m_dx(dx), m_dy(dy), m_closed(true) {} //-------------------------------------------------------------------- void init(const int8u* data, unsigned size, double dx, double dy) { m_data = data; m_end = data + size; m_ptr = data; m_dx = dx; m_dy = dy; m_closed = true; } //-------------------------------------------------------------------- void rewind(unsigned) { m_ptr = m_data; m_closed = true; } //-------------------------------------------------------------------- unsigned vertex(double* x, double* y) { if(m_data == 0 || m_ptr > m_end) { *x = 0; *y = 0; return path_cmd_stop; } if(m_ptr == m_end) { *x = 0; *y = 0; m_ptr += sizeof(vertex_integer_type); return path_cmd_end_poly | path_flags_close; } vertex_integer_type v; memcpy(&v, m_ptr, sizeof(vertex_integer_type)); unsigned cmd = v.vertex(x, y, m_dx, m_dy); if(is_move_to(cmd) && !m_closed) { *x = 0; *y = 0; m_closed = true; return path_cmd_end_poly | path_flags_close; } m_closed = false; m_ptr += sizeof(vertex_integer_type); return cmd; } private: const int8u* m_data; const int8u* m_end; const int8u* m_ptr; double m_dx; double m_dy; bool m_closed; }; } #endif aggdraw-1.3.14/agg2/include/agg_pattern_filters_rgba8.h000066400000000000000000000070511417726601400227510ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_PATTERN_FILTERS_RGBA8_INCLUDED #define AGG_PATTERN_FILTERS_RGBA8_INCLUDED #include "agg_basics.h" #include "agg_line_aa_basics.h" #include "agg_color_rgba8.h" namespace agg { //=======================================================pattern_filter_nn template struct pattern_filter_nn { typedef ColorT color_type; static unsigned dilation() { return 0; } static void pixel_low_res(color_type const* const* buf, color_type* p, int x, int y) { *p = buf[y][x]; } static void pixel_high_res(color_type const* const* buf, color_type* p, int x, int y) { *p = buf[y >> line_subpixel_shift] [x >> line_subpixel_shift]; } }; typedef pattern_filter_nn pattern_filter_nn_rgba8; //===========================================pattern_filter_bilinear_rgba8 struct pattern_filter_bilinear_rgba8 { typedef rgba8 color_type; static unsigned dilation() { return 1; } static void pixel_low_res(color_type const* const* buf, color_type* p, int x, int y) { *p = buf[y][x]; } static void pixel_high_res(color_type const* const* buf, color_type* p, int x, int y) { int r, g, b, a; r = g = b = a = line_subpixel_size * line_subpixel_size / 2; int weight; int x_lr = x >> line_subpixel_shift; int y_lr = y >> line_subpixel_shift; x &= line_subpixel_mask; y &= line_subpixel_mask; const color_type* ptr = buf[y_lr] + x_lr; weight = (line_subpixel_size - x) * (line_subpixel_size - y); r += weight * ptr->r; g += weight * ptr->g; b += weight * ptr->b; a += weight * ptr->a; ++ptr; weight = x * (line_subpixel_size - y); r += weight * ptr->r; g += weight * ptr->g; b += weight * ptr->b; a += weight * ptr->a; ptr = buf[y_lr + 1] + x_lr; weight = (line_subpixel_size - x) * y; r += weight * ptr->r; g += weight * ptr->g; b += weight * ptr->b; a += weight * ptr->a; ++ptr; weight = x * y; r += weight * ptr->r; g += weight * ptr->g; b += weight * ptr->b; a += weight * ptr->a; p->r = (int8u)(r >> line_subpixel_shift * 2); p->g = (int8u)(g >> line_subpixel_shift * 2); p->b = (int8u)(b >> line_subpixel_shift * 2); p->a = (int8u)(a >> line_subpixel_shift * 2); } }; } #endif aggdraw-1.3.14/agg2/include/agg_pixfmt_amask_adaptor.h000066400000000000000000000166721417726601400226670ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_PIXFMT_AMASK_ADAPTOR_INCLUDED #define AGG_PIXFMT_AMASK_ADAPTOR_INCLUDED #include #include "agg_rendering_buffer.h" namespace agg { //==================================================pixfmt_amask_adaptor template class pixfmt_amask_adaptor { public: typedef PixFmt pixfmt_type; typedef typename pixfmt_type::color_type color_type; typedef AlphaMask amask_type; typedef typename amask_type::cover_type cover_type; private: enum { span_extra_tail = 256 }; void realloc_span(unsigned len) { if(len > m_max_len) { delete [] m_span; m_span = new cover_type[m_max_len = len + span_extra_tail]; } } void init_span(unsigned len) { realloc_span(len); // ATTN! May work incorrectly if cover_type is more that one byte memset(m_span, amask_type::cover_full, len * sizeof(cover_type)); } void init_span(unsigned len, const cover_type* covers) { realloc_span(len); memcpy(m_span, covers, len * sizeof(cover_type)); } public: ~pixfmt_amask_adaptor() { delete [] m_span; } pixfmt_amask_adaptor(pixfmt_type& pixf, const amask_type& mask) : m_pixf(&pixf), m_mask(&mask), m_span(0), m_max_len(0) {} void attach_pixfmt(pixfmt_type& pixf) { m_pixf = &pixf; } void attach_alpha_mask(const amask_type& mask) { m_mask = &mask; } //-------------------------------------------------------------------- unsigned width() const { return m_pixf->width(); } unsigned height() const { return m_pixf->height(); } //-------------------------------------------------------------------- color_type pixel(int x, int y) { return m_pixf->pixel(x, y); } //-------------------------------------------------------------------- void copy_pixel(int x, int y, const color_type& c) { m_pixf->blend_pixel(x, y, c, m_mask->pixel(x, y)); } //-------------------------------------------------------------------- void blend_pixel(int x, int y, const color_type& c, cover_type cover) { m_pixf->blend_pixel(x, y, c, m_mask->combine_pixel(x, y, cover)); } //-------------------------------------------------------------------- void copy_hline(int x, int y, unsigned len, const color_type& c) { realloc_span(len); m_mask->fill_hspan(x, y, m_span, len); m_pixf->blend_solid_hspan(x, y, len, c, m_span); } //-------------------------------------------------------------------- void blend_hline(int x, int y, unsigned len, const color_type& c, cover_type cover) { init_span(len); m_mask->combine_hspan(x, y, m_span, len); m_pixf->blend_solid_hspan(x, y, len, c, m_span); } //-------------------------------------------------------------------- void copy_vline(int x, int y, unsigned len, const color_type& c) { realloc_span(len); m_mask->fill_vspan(x, y, m_span, len); m_pixf->blend_solid_vspan(x, y, len, c, m_span); } //-------------------------------------------------------------------- void blend_vline(int x, int y, unsigned len, const color_type& c, cover_type cover) { init_span(len); m_mask->combine_vspan(x, y, m_span, len); m_pixf->blend_solid_vspan(x, y, len, c, m_span); } //-------------------------------------------------------------------- void copy_from(const rendering_buffer& from, int xdst, int ydst, int xsrc, int ysrc, unsigned len) { m_pixf->copy_from(from, xdst, ydst, xsrc, ysrc, len); } //-------------------------------------------------------------------- void blend_solid_hspan(int x, int y, unsigned len, const color_type& c, const cover_type* covers) { init_span(len, covers); m_mask->combine_hspan(x, y, m_span, len); m_pixf->blend_solid_hspan(x, y, len, c, m_span); } //-------------------------------------------------------------------- void blend_solid_vspan(int x, int y, unsigned len, const color_type& c, const cover_type* covers) { init_span(len, covers); m_mask->combine_vspan(x, y, m_span, len); m_pixf->blend_solid_vspan(x, y, len, c, m_span); } //-------------------------------------------------------------------- void blend_color_hspan(int x, int y, unsigned len, const color_type* colors, const cover_type* covers, cover_type cover = cover_full) { if(covers) { init_span(len, covers); m_mask->combine_hspan(x, y, m_span, len); } else { realloc_span(len); m_mask->fill_hspan(x, y, m_span, len); } m_pixf->blend_color_hspan(x, y, len, colors, m_span, cover); } //-------------------------------------------------------------------- void blend_color_vspan(int x, int y, unsigned len, const color_type* colors, const cover_type* covers, cover_type cover = cover_full) { if(covers) { init_span(len, covers); m_mask->combine_vspan(x, y, m_span, len); } else { realloc_span(len); m_mask->fill_vspan(x, y, m_span, len); } m_pixf->blend_color_vspan(x, y, len, colors, m_span, cover); } private: pixfmt_type* m_pixf; const amask_type* m_mask; cover_type* m_span; unsigned m_max_len; }; } #endif aggdraw-1.3.14/agg2/include/agg_pixfmt_gray8.h000066400000000000000000000247011417726601400211030ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_PIXFMT_GRAY8_INCLUDED #define AGG_PIXFMT_GRAY8_INCLUDED #include #include "agg_basics.h" #include "agg_gray8.h" #include "agg_rendering_buffer.h" namespace agg { //======================================================pixfmt_gray8_base template class pixfmt_gray8_base { public: typedef gray8 color_type; //-------------------------------------------------------------------- pixfmt_gray8_base(rendering_buffer& rb) : m_rbuf(&rb) { } //-------------------------------------------------------------------- unsigned width() const { return m_rbuf->width(); } unsigned height() const { return m_rbuf->height(); } //-------------------------------------------------------------------- color_type pixel(int x, int y) { return color_type(m_rbuf->row(y)[x * Step + Offset]); } //-------------------------------------------------------------------- void copy_pixel(int x, int y, const color_type& c) { m_rbuf->row(y)[x * Step + Offset] = (int8u)c.v; } //-------------------------------------------------------------------- void blend_pixel(int x, int y, const color_type& c, int8u cover) { int8u* p = m_rbuf->row(y) + x * Step + Offset; int v = *p; int alpha = int(cover) * c.a; *p = (int8u)((((c.v - v) * alpha) + (v << 16)) >> 16); } //-------------------------------------------------------------------- void copy_hline(int x, int y, unsigned len, const color_type& c) { int8u* p = m_rbuf->row(y) + x * Step + Offset; do { *p = (int8u)c.v; p += Step; } while(--len); } //-------------------------------------------------------------------- void copy_vline(int x, int y, unsigned len, const color_type& c) { int8u* p = m_rbuf->row(y) + x * Step + Offset; do { *p = (int8u)c.v; p += m_rbuf->stride(); } while(--len); } //-------------------------------------------------------------------- void blend_hline(int x, int y, unsigned len, const color_type& c, int8u cover) { int8u* p = m_rbuf->row(y) + x * Step + Offset; int alpha = int(cover) * c.a; if(alpha == 255*255) { do { *p = (int8u)c.v; p += Step; } while(--len); } else { do { int v = *p; *p = (int8u)((((c.v - v) * alpha) + (v << 16)) >> 16); p += Step; } while(--len); } } //-------------------------------------------------------------------- void blend_vline(int x, int y, unsigned len, const color_type& c, int8u cover) { int8u* p = m_rbuf->row(y) + x * Step + Offset; int alpha = int(cover) * c.a; if(alpha == 255*255) { do { *p = (int8u)c.v; p += m_rbuf->stride(); } while(--len); } else { do { int v = *p; *p = (int8u)((((c.v - v) * alpha) + (v << 16)) >> 16); p += m_rbuf->stride(); } while(--len); } } //-------------------------------------------------------------------- void copy_from(const rendering_buffer& from, int xdst, int ydst, int xsrc, int ysrc, unsigned len) { memmove(m_rbuf->row(ydst) + xdst * Step + Offset, (const void*)(from.row(ysrc) + xsrc * Step + Offset), len * Step); } //-------------------------------------------------------------------- void blend_solid_hspan(int x, int y, unsigned len, const color_type& c, const int8u* covers) { int8u* p = m_rbuf->row(y) + x * Step + Offset; do { int alpha = int(*covers++) * c.a; if(alpha) { if(alpha == 255*255) { *p = (int8u)c.v; } else { int v = *p; *p = (int8u)((((c.v - v) * alpha) + (v << 16)) >> 16); } } p += Step; } while(--len); } //-------------------------------------------------------------------- void blend_solid_vspan(int x, int y, unsigned len, const color_type& c, const int8u* covers) { int8u* p = m_rbuf->row(y) + x * Step + Offset; do { int alpha = int(*covers++) * c.a; if(alpha) { if(alpha == 255*255) { *p = (int8u)c.v; } else { int v = *p; *p = (int8u)((((c.v - v) * alpha) + (v << 16)) >> 16); } } p += m_rbuf->stride(); } while(--len); } //-------------------------------------------------------------------- void blend_color_hspan(int x, int y, unsigned len, const color_type* colors, const int8u* covers, int8u cover) { int8u* p = m_rbuf->row(y) + x * Step + Offset; do { int alpha = colors->a * (covers ? int(*covers++) : int(cover)); if(alpha) { if(alpha == 255*255) { *p = (int8u)colors->v; } else { int v = *p; *p = (int8u)((((colors->v - v) * alpha) + (v << 16)) >> 16); } } p += Step; ++colors; } while(--len); } //-------------------------------------------------------------------- void blend_color_vspan(int x, int y, unsigned len, const color_type* colors, const int8u* covers, int8u cover) { int8u* p = m_rbuf->row(y) + x * Step + Offset; do { int alpha = colors->a * (covers ? int(*covers++) : int(cover)); if(alpha) { if(alpha == 255*255) { *p = (int8u)colors->v; } else { int v = *p; *p = (int8u)((((colors->v - v) * alpha) + (v << 16)) >> 16); } } p += m_rbuf->stride(); ++colors; } while(--len); } private: rendering_buffer* m_rbuf; }; typedef pixfmt_gray8_base<1, 0> pixfmt_gray8; //----pixfmt_gray8 typedef pixfmt_gray8_base<3, 0> pixfmt_gray8_rgb24r; //----pixfmt_gray8_rgb24r typedef pixfmt_gray8_base<3, 1> pixfmt_gray8_rgb24g; //----pixfmt_gray8_rgb24g typedef pixfmt_gray8_base<3, 2> pixfmt_gray8_rgb24b; //----pixfmt_gray8_rgb24b typedef pixfmt_gray8_base<3, 2> pixfmt_gray8_bgr24r; //----pixfmt_gray8_bgr24r typedef pixfmt_gray8_base<3, 1> pixfmt_gray8_bgr24g; //----pixfmt_gray8_bgr24g typedef pixfmt_gray8_base<3, 0> pixfmt_gray8_bgr24b; //----pixfmt_gray8_bgr24b typedef pixfmt_gray8_base<4, 0> pixfmt_gray8_rgba32r; //----pixfmt_gray8_rgba32r typedef pixfmt_gray8_base<4, 1> pixfmt_gray8_rgba32g; //----pixfmt_gray8_rgba32g typedef pixfmt_gray8_base<4, 2> pixfmt_gray8_rgba32b; //----pixfmt_gray8_rgba32b typedef pixfmt_gray8_base<4, 3> pixfmt_gray8_rgba32a; //----pixfmt_gray8_rgba32a typedef pixfmt_gray8_base<4, 1> pixfmt_gray8_argb32r; //----pixfmt_gray8_argb32r typedef pixfmt_gray8_base<4, 2> pixfmt_gray8_argb32g; //----pixfmt_gray8_argb32g typedef pixfmt_gray8_base<4, 3> pixfmt_gray8_argb32b; //----pixfmt_gray8_argb32b typedef pixfmt_gray8_base<4, 0> pixfmt_gray8_argb32a; //----pixfmt_gray8_argb32a typedef pixfmt_gray8_base<4, 2> pixfmt_gray8_bgra32r; //----pixfmt_gray8_bgra32r typedef pixfmt_gray8_base<4, 1> pixfmt_gray8_bgra32g; //----pixfmt_gray8_bgra32g typedef pixfmt_gray8_base<4, 0> pixfmt_gray8_bgra32b; //----pixfmt_gray8_bgra32b typedef pixfmt_gray8_base<4, 3> pixfmt_gray8_bgra32a; //----pixfmt_gray8_bgra32a typedef pixfmt_gray8_base<4, 3> pixfmt_gray8_abgr32r; //----pixfmt_gray8_abgr32r typedef pixfmt_gray8_base<4, 2> pixfmt_gray8_abgr32g; //----pixfmt_gray8_abgr32g typedef pixfmt_gray8_base<4, 1> pixfmt_gray8_abgr32b; //----pixfmt_gray8_abgr32b typedef pixfmt_gray8_base<4, 0> pixfmt_gray8_abgr32a; //----pixfmt_gray8_abgr32a } #endif aggdraw-1.3.14/agg2/include/agg_pixfmt_rgb24.h000066400000000000000000000301231417726601400207640ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_PIXFMT_RGB24_INCLUDED #define AGG_PIXFMT_RGB24_INCLUDED #include #include "agg_basics.h" #include "agg_color_rgba8.h" #include "agg_rendering_buffer.h" namespace agg { //=====================================================pixel_formats_rgb24 template class pixel_formats_rgb24 { public: typedef rgba8 color_type; //-------------------------------------------------------------------- pixel_formats_rgb24(rendering_buffer& rb) : m_rbuf(&rb) { } //-------------------------------------------------------------------- unsigned width() const { return m_rbuf->width(); } unsigned height() const { return m_rbuf->height(); } //-------------------------------------------------------------------- color_type pixel(int x, int y) { int8u* p = m_rbuf->row(y) + x + x + x; return color_type(p[Order::R], p[Order::G], p[Order::B]); } //-------------------------------------------------------------------- void copy_pixel(int x, int y, const color_type& c) { int8u* p = m_rbuf->row(y) + x + x + x; p[Order::R] = (int8u)c.r; p[Order::G] = (int8u)c.g; p[Order::B] = (int8u)c.b; } //-------------------------------------------------------------------- void blend_pixel(int x, int y, const color_type& c, int8u cover) { int8u* p = m_rbuf->row(y) + x + x + x; int alpha = int(cover) * c.a; if(alpha == 255*255) { p[Order::R] = (int8u)c.r; p[Order::G] = (int8u)c.g; p[Order::B] = (int8u)c.b; } else { int r = p[Order::R]; int g = p[Order::G]; int b = p[Order::B]; p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16); p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16); p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16); } } //-------------------------------------------------------------------- void copy_hline(int x, int y, unsigned len, const color_type& c) { int8u* p = m_rbuf->row(y) + x + x + x; do { p[Order::R] = (int8u)c.r; p[Order::G] = (int8u)c.g; p[Order::B] = (int8u)c.b; p += 3; } while(--len); } //-------------------------------------------------------------------- void copy_vline(int x, int y, unsigned len, const color_type& c) { int8u* p = m_rbuf->row(y) + x + x + x; do { p[Order::R] = (int8u)c.r; p[Order::G] = (int8u)c.g; p[Order::B] = (int8u)c.b; p += m_rbuf->stride(); } while(--len); } //-------------------------------------------------------------------- void blend_hline(int x, int y, unsigned len, const color_type& c, int8u cover) { int8u* p = m_rbuf->row(y) + x + x + x; int alpha = int(cover) * c.a; if(alpha == 255*255) { do { p[Order::R] = (int8u)c.r; p[Order::G] = (int8u)c.g; p[Order::B] = (int8u)c.b; p += 3; } while(--len); } else { do { int r = p[Order::R]; int g = p[Order::G]; int b = p[Order::B]; p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16); p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16); p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16); p += 3; } while(--len); } } //-------------------------------------------------------------------- void blend_vline(int x, int y, unsigned len, const color_type& c, int8u cover) { int8u* p = m_rbuf->row(y) + x + x + x; int alpha = int(cover) * c.a; if(alpha == 255*255) { do { p[Order::R] = (int8u)c.r; p[Order::G] = (int8u)c.g; p[Order::B] = (int8u)c.b; p += m_rbuf->stride(); } while(--len); } else { do { int r = p[Order::R]; int g = p[Order::G]; int b = p[Order::B]; p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16); p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16); p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16); p += m_rbuf->stride(); } while(--len); } } //-------------------------------------------------------------------- void copy_from(const rendering_buffer& from, int xdst, int ydst, int xsrc, int ysrc, unsigned len) { memmove(m_rbuf->row(ydst) + xdst * 3, (const void*)(from.row(ysrc) + xsrc * 3), len * 3); } //-------------------------------------------------------------------- void blend_solid_hspan(int x, int y, unsigned len, const color_type& c, const int8u* covers) { int8u* p = m_rbuf->row(y) + x + x + x; do { int alpha = int(*covers++) * c.a; if(alpha) { if(alpha == 255*255) { p[Order::R] = (int8u)c.r; p[Order::G] = (int8u)c.g; p[Order::B] = (int8u)c.b; } else { int r = (int8u)p[Order::R]; int g = (int8u)p[Order::G]; int b = (int8u)p[Order::B]; p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16); p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16); p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16); } } p += 3; } while(--len); } //-------------------------------------------------------------------- void blend_solid_vspan(int x, int y, unsigned len, const color_type& c, const int8u* covers) { int8u* p = m_rbuf->row(y) + x + x + x; do { int alpha = int(*covers++) * c.a; if(alpha) { if(alpha == 255*255) { p[Order::R] = (int8u)c.r; p[Order::G] = (int8u)c.g; p[Order::B] = (int8u)c.b; } else { int r = p[Order::R]; int g = p[Order::G]; int b = p[Order::B]; p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16); p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16); p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16); } } p += m_rbuf->stride(); } while(--len); } //-------------------------------------------------------------------- void blend_color_hspan(int x, int y, unsigned len, const color_type* colors, const int8u* covers, const int8u cover) { int8u* p = m_rbuf->row(y) + x + x + x; do { int alpha = colors->a * (covers ? int(*covers++) : int(cover)); if(alpha) { if(alpha == 255*255) { p[Order::R] = (int8u)colors->r; p[Order::G] = (int8u)colors->g; p[Order::B] = (int8u)colors->b; } else { int r = p[Order::R]; int g = p[Order::G]; int b = p[Order::B]; p[Order::R] = (int8u)((((colors->r - r) * alpha) + (r << 16)) >> 16); p[Order::G] = (int8u)((((colors->g - g) * alpha) + (g << 16)) >> 16); p[Order::B] = (int8u)((((colors->b - b) * alpha) + (b << 16)) >> 16); } } p += 3; ++colors; } while(--len); } //-------------------------------------------------------------------- void blend_color_vspan(int x, int y, unsigned len, const color_type* colors, const int8u* covers, const int8u cover) { int8u* p = m_rbuf->row(y) + x + x + x; do { int alpha = colors->a * (covers ? int(*covers++) : int(cover)); if(alpha) { if(alpha == 255*255) { p[Order::R] = (int8u)colors->r; p[Order::G] = (int8u)colors->g; p[Order::B] = (int8u)colors->b; } else { int r = p[Order::R]; int g = p[Order::G]; int b = p[Order::B]; p[Order::R] = (int8u)((((colors->r - r) * alpha) + (r << 16)) >> 16); p[Order::G] = (int8u)((((colors->g - g) * alpha) + (g << 16)) >> 16); p[Order::B] = (int8u)((((colors->b - b) * alpha) + (b << 16)) >> 16); } } p += m_rbuf->stride(); ++colors; } while(--len); } private: rendering_buffer* m_rbuf; }; typedef pixel_formats_rgb24 pixfmt_rgb24; //----pixfmt_rgb24 typedef pixel_formats_rgb24 pixfmt_bgr24; //----pixfmt_bgr24 } #endif aggdraw-1.3.14/agg2/include/agg_pixfmt_rgb24_gamma.h000066400000000000000000000252711417726601400221360ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_PIXFMT_RGB24_GAMMA_INCLUDED #define AGG_PIXFMT_RGB24_GAMMA_INCLUDED #include #include "agg_basics.h" #include "agg_color_rgba8.h" #include "agg_rendering_buffer.h" #include "agg_gamma_lut.h" namespace agg { //================================================pixel_formats_rgb24_gamma template class pixel_formats_rgb24_gamma { public: typedef rgba8 color_type; typedef Gamma gamma_type; private: //-------------------------------------------------------------------- inline void blend_pix(int8u* p, const color_type& c, int alpha) { int r = m_gamma->dir(p[Order::R]); int g = m_gamma->dir(p[Order::G]); int b = m_gamma->dir(p[Order::B]); p[Order::R] = m_gamma->inv((((m_gamma->dir(c.r) - r) * alpha) + (r << 16)) >> 16); p[Order::G] = m_gamma->inv((((m_gamma->dir(c.g) - g) * alpha) + (g << 16)) >> 16); p[Order::B] = m_gamma->inv((((m_gamma->dir(c.b) - b) * alpha) + (b << 16)) >> 16); } //-------------------------------------------------------------------- inline void copy_or_blend_pix(int8u* p, const color_type& c, int cover) { int alpha = int(c.a) * cover; if(alpha) { if(alpha == 255*255) { p[Order::R] = (int8u)c.r; p[Order::G] = (int8u)c.g; p[Order::B] = (int8u)c.b; } else { blend_pix(p, c, alpha); } } } //-------------------------------------------------------------------- inline void copy_or_blend_pix(int8u* p, const color_type& c) { if(c.a) { if(c.a == 255) { p[Order::R] = (int8u)c.r; p[Order::G] = (int8u)c.g; p[Order::B] = (int8u)c.b; } else { int r = m_gamma->dir(p[Order::R]); int g = m_gamma->dir(p[Order::G]); int b = m_gamma->dir(p[Order::B]); p[Order::R] = m_gamma->inv((((m_gamma->dir(c.r) - r) * c.a) + (r << 8)) >> 8); p[Order::G] = m_gamma->inv((((m_gamma->dir(c.g) - g) * c.a) + (g << 8)) >> 8); p[Order::B] = m_gamma->inv((((m_gamma->dir(c.b) - b) * c.a) + (b << 8)) >> 8); } } } public: //-------------------------------------------------------------------- pixel_formats_rgb24_gamma(rendering_buffer& rb, const gamma_type& g) : m_rbuf(&rb), m_gamma(&g) {} //-------------------------------------------------------------------- void gamma(const gamma_type& g) { m_gamma = &g; } const gamma_type& gamma() const { return *m_gamma; } //-------------------------------------------------------------------- unsigned width() const { return m_rbuf->width(); } unsigned height() const { return m_rbuf->height(); } //-------------------------------------------------------------------- color_type pixel(int x, int y) { int8u* p = m_rbuf->row(y) + x + x + x; return color_type(p[Order::R], p[Order::G], p[Order::B]); } //-------------------------------------------------------------------- void copy_pixel(int x, int y, const color_type& c) { int8u* p = m_rbuf->row(y) + x + x + x; p[Order::R] = (int8u)c.r; p[Order::G] = (int8u)c.g; p[Order::B] = (int8u)c.b; } //-------------------------------------------------------------------- void blend_pixel(int x, int y, const color_type& c, int8u cover) { copy_or_blend_pix(m_rbuf->row(y) + x + x + x, c, cover); } //-------------------------------------------------------------------- void copy_hline(int x, int y, unsigned len, const color_type& c) { int8u* p = m_rbuf->row(y) + x + x + x; do { p[Order::R] = (int8u)c.r; p[Order::G] = (int8u)c.g; p[Order::B] = (int8u)c.b; p += 3; } while(--len); } //-------------------------------------------------------------------- void copy_vline(int x, int y, unsigned len, const color_type& c) { int8u* p = m_rbuf->row(y) + x + x + x; do { p[Order::R] = (int8u)c.r; p[Order::G] = (int8u)c.g; p[Order::B] = (int8u)c.b; p += m_rbuf->stride(); } while(--len); } //-------------------------------------------------------------------- void blend_hline(int x, int y, unsigned len, const color_type& c, int8u cover) { int8u* p = m_rbuf->row(y) + x + x + x; int alpha = int(cover) * c.a; if(alpha == 255*255) { do { p[Order::R] = (int8u)c.r; p[Order::G] = (int8u)c.g; p[Order::B] = (int8u)c.b; p += 3; } while(--len); } else { do { blend_pix(p, c, alpha); p += 3; } while(--len); } } //-------------------------------------------------------------------- void blend_vline(int x, int y, unsigned len, const color_type& c, int8u cover) { int8u* p = m_rbuf->row(y) + x + x + x; int alpha = int(cover) * c.a; if(alpha == 255*255) { do { p[Order::R] = (int8u)c.r; p[Order::G] = (int8u)c.g; p[Order::B] = (int8u)c.b; p += m_rbuf->stride(); } while(--len); } else { do { blend_pix(p, c, alpha); p += m_rbuf->stride(); } while(--len); } } //-------------------------------------------------------------------- void copy_from(const rendering_buffer& from, int xdst, int ydst, int xsrc, int ysrc, unsigned len) { memmove(m_rbuf->row(ydst) + xdst * 3, (const void*)(from.row(ysrc) + xsrc * 3), len * 3); } //-------------------------------------------------------------------- void blend_solid_hspan(int x, int y, unsigned len, const color_type& c, const int8u* covers) { int8u* p = m_rbuf->row(y) + x + x + x; do { copy_or_blend_pix(p, c, *covers++); p += 3; } while(--len); } //-------------------------------------------------------------------- void blend_solid_vspan(int x, int y, unsigned len, const color_type& c, const int8u* covers) { int8u* p = m_rbuf->row(y) + x + x + x; do { copy_or_blend_pix(p, c, *covers++); p += m_rbuf->stride(); } while(--len); } //-------------------------------------------------------------------- void blend_color_hspan(int x, int y, unsigned len, const color_type* colors, const int8u* covers, int8u cover) { int8u* p = m_rbuf->row(y) + x + x + x; do { copy_or_blend_pix(p, *colors++, covers ? *covers++ : cover); p += 3; } while(--len); } //-------------------------------------------------------------------- void blend_color_vspan(int x, int y, unsigned len, const color_type* colors, const int8u* covers, int8u cover) { int8u* p = m_rbuf->row(y) + x + x + x; do { copy_or_blend_pix(p, *colors++, covers ? *covers++ : cover); p += m_rbuf->stride(); } while(--len); } private: rendering_buffer* m_rbuf; const gamma_type* m_gamma; }; //-----------------------------------------------------pixfmt_rgb24_gamma template class pixfmt_rgb24_gamma : public pixel_formats_rgb24_gamma { public: pixfmt_rgb24_gamma(rendering_buffer& rb, const Gamma& g) : pixel_formats_rgb24_gamma(rb, g) {} }; //-----------------------------------------------------pixfmt_bgr24_gamma template class pixfmt_bgr24_gamma : public pixel_formats_rgb24_gamma { public: pixfmt_bgr24_gamma(rendering_buffer& rb, const Gamma& g) : pixel_formats_rgb24_gamma(rb, g) {} }; } #endif aggdraw-1.3.14/agg2/include/agg_pixfmt_rgb24_pre.h000066400000000000000000000226621417726601400216430ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_PIXFMT_RGB24_PRE_INCLUDED #define AGG_PIXFMT_RGB24_PRE_INCLUDED #include #include "agg_basics.h" #include "agg_color_rgba8.h" #include "agg_rendering_buffer.h" namespace agg { //==================================================pixel_formats_rgb24_pre template class pixel_formats_rgb24_pre { public: typedef rgba8 color_type; private: //-------------------------------------------------------------------- static inline void copy_pix(int8u* p, const color_type& c) { p[Order::R] = (int8u)c.r; p[Order::G] = (int8u)c.g; p[Order::B] = (int8u)c.b; } //-------------------------------------------------------------------- static inline void blend_pix(int8u* p, const color_type& c, unsigned cover, unsigned alpha) { p[Order::R] = (int8u)((p[Order::R] * alpha + ((c.r * cover) << 8)) >> 16); p[Order::G] = (int8u)((p[Order::G] * alpha + ((c.g * cover) << 8)) >> 16); p[Order::B] = (int8u)((p[Order::B] * alpha + ((c.b * cover) << 8)) >> 16); } //-------------------------------------------------------------------- static inline void copy_or_blend_pix(int8u* p, const color_type& c, unsigned cover) { unsigned alpha = 65535 - cover * c.a; if(alpha < 65535) { if(alpha <= 65535-255*255) { copy_pix(p, c); } else { blend_pix(p, c, cover, alpha); } } } //-------------------------------------------------------------------- static inline void copy_or_blend_pix(int8u* p, const color_type& c) { unsigned alpha = 255 - c.a; if(alpha < 255) { if(alpha == 0) { copy_pix(p, c); } else { p[Order::R] = (int8u)((p[Order::R] * alpha + (c.r << 8)) >> 8); p[Order::G] = (int8u)((p[Order::G] * alpha + (c.g << 8)) >> 8); p[Order::B] = (int8u)((p[Order::B] * alpha + (c.b << 8)) >> 8); } } } public: //-------------------------------------------------------------------- pixel_formats_rgb24_pre(rendering_buffer& rb) : m_rbuf(&rb) { } //-------------------------------------------------------------------- unsigned width() const { return m_rbuf->width(); } unsigned height() const { return m_rbuf->height(); } //-------------------------------------------------------------------- color_type pixel(int x, int y) { int8u* p = m_rbuf->row(y) + x + x + x; return color_type(p[Order::R], p[Order::G], p[Order::B]); } //-------------------------------------------------------------------- void copy_pixel(int x, int y, const color_type& c) { int8u* p = m_rbuf->row(y) + x + x + x; p[Order::R] = (int8u)c.r; p[Order::G] = (int8u)c.g; p[Order::B] = (int8u)c.b; } //-------------------------------------------------------------------- void blend_pixel(int x, int y, const color_type& c, int8u cover) { copy_or_blend_pix(m_rbuf->row(y) + x + x + x, c, cover); } //-------------------------------------------------------------------- void copy_hline(int x, int y, unsigned len, const color_type& c) { int8u* p = m_rbuf->row(y) + x + x + x; do { p[Order::R] = (int8u)c.r; p[Order::G] = (int8u)c.g; p[Order::B] = (int8u)c.b; p += 3; } while(--len); } //-------------------------------------------------------------------- void copy_vline(int x, int y, unsigned len, const color_type& c) { int8u* p = m_rbuf->row(y) + x + x + x; do { p[Order::R] = (int8u)c.r; p[Order::G] = (int8u)c.g; p[Order::B] = (int8u)c.b; p += m_rbuf->stride(); } while(--len); } //-------------------------------------------------------------------- void blend_hline(int x, int y, unsigned len, const color_type& c, int8u cover) { int8u* p = m_rbuf->row(y) + x + x + x; unsigned alpha = unsigned(cover) * c.a; if(alpha == 255*255) { do { p[Order::R] = (int8u)c.r; p[Order::G] = (int8u)c.g; p[Order::B] = (int8u)c.b; p += 3; } while(--len); } else { alpha = 65535 - alpha; do { blend_pix(p, c, cover, alpha); p += 3; } while(--len); } } //-------------------------------------------------------------------- void blend_vline(int x, int y, unsigned len, const color_type& c, int8u cover) { int8u* p = m_rbuf->row(y) + x + x + x; unsigned alpha = unsigned(cover) * c.a; if(alpha == 255*255) { do { p[Order::R] = (int8u)c.r; p[Order::G] = (int8u)c.g; p[Order::B] = (int8u)c.b; p += m_rbuf->stride(); } while(--len); } else { alpha = 65535 - alpha; do { blend_pix(p, c, cover, alpha); p += m_rbuf->stride(); } while(--len); } } //-------------------------------------------------------------------- void copy_from(const rendering_buffer& from, int xdst, int ydst, int xsrc, int ysrc, unsigned len) { memmove(m_rbuf->row(ydst) + xdst * 3, (const void*)(from.row(ysrc) + xsrc * 3), len * 3); } //-------------------------------------------------------------------- void blend_solid_hspan(int x, int y, unsigned len, const color_type& c, const int8u* covers) { int8u* p = m_rbuf->row(y) + x + x + x; do { copy_or_blend_pix(p, c, *covers++); p += 3; } while(--len); } //-------------------------------------------------------------------- void blend_solid_vspan(int x, int y, unsigned len, const color_type& c, const int8u* covers) { int8u* p = m_rbuf->row(y) + x + x + x; do { copy_or_blend_pix(p, c, *covers++); p += m_rbuf->stride(); } while(--len); } //-------------------------------------------------------------------- void blend_color_hspan(int x, int y, unsigned len, const color_type* colors, const int8u* covers, int8u cover) { int8u* p = m_rbuf->row(y) + x + x + x; do { copy_or_blend_pix(p, *colors++, covers ? *covers++ : cover); p += 3; } while(--len); } //-------------------------------------------------------------------- void blend_color_vspan(int x, int y, unsigned len, const color_type* colors, const int8u* covers, int8u cover) { int8u* p = m_rbuf->row(y) + x + x + x; do { copy_or_blend_pix(p, *colors++, covers ? *covers++ : cover); p += m_rbuf->stride(); } while(--len); } private: rendering_buffer* m_rbuf; }; typedef pixel_formats_rgb24_pre pixfmt_rgb24_pre; //----pixfmt_rgb24_pre typedef pixel_formats_rgb24_pre pixfmt_bgr24_pre; //----pixfmt_bgr24_pre } #endif aggdraw-1.3.14/agg2/include/agg_pixfmt_rgb555.h000066400000000000000000000267611417726601400210720ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_PIXFMT_RGB555_INCLUDED #define AGG_PIXFMT_RGB555_INCLUDED #include #include "agg_basics.h" #include "agg_color_rgba8.h" #include "agg_rendering_buffer.h" namespace agg { //------------------------------------------------------------------rgb555 inline int16u rgb555(unsigned r, unsigned g, unsigned b) { return (int16u)(((r & 0xF8) << 7) | ((g & 0xF8) << 2) | (b >> 3)); } //===========================================================pixfmt_rgb555 class pixfmt_rgb555 { public: typedef rgba8 color_type; //-------------------------------------------------------------------- pixfmt_rgb555(rendering_buffer& rb) : m_rbuf(&rb) { } //-------------------------------------------------------------------- unsigned width() const { return m_rbuf->width(); } unsigned height() const { return m_rbuf->height(); } //-------------------------------------------------------------------- color_type pixel(int x, int y) { unsigned rgb = ((int16u*)(m_rbuf->row(y)))[x]; return color_type((rgb >> 7) & 0xF8, (rgb >> 2) & 0xF8, (rgb << 3) & 0xF8); } //-------------------------------------------------------------------- void copy_pixel(int x, int y, const color_type& c) { ((int16u*)(m_rbuf->row(y)))[x] = rgb555(c.r, c.g, c.b); } //-------------------------------------------------------------------- void blend_pixel(int x, int y, const color_type& c, int8u cover) { int alpha = int(cover) * c.a; int16u* p = (int16u*)(m_rbuf->row(y)) + x; if(alpha == 255*255) { *p = rgb555(c.r, c.g, c.b); } else { int16u rgb = *p; int r = (rgb >> 7) & 0xF8; int g = (rgb >> 2) & 0xF8; int b = (rgb << 3) & 0xF8; *p = (int16u) ((((((c.r - r) * alpha) + (r << 16)) >> 9) & 0x7C00) | (((((c.g - g) * alpha) + (g << 16)) >> 14) & 0x3E0) | ((((c.b - b) * alpha) + (b << 16)) >> 19)); } } //-------------------------------------------------------------------- void copy_hline(int x, int y, unsigned len, const color_type& c) { int16u* p = (int16u*)(m_rbuf->row(y)) + x; int16u v = rgb555(c.r, c.g, c.b); do { *p++ = v; } while(--len); } //-------------------------------------------------------------------- void copy_vline(int x, int y, unsigned len, const color_type& c) { int8u* p = m_rbuf->row(y) + (x << 1); int16u v = rgb555(c.r, c.g, c.b); do { *(int16u*)p = v; p += m_rbuf->stride(); } while(--len); } //-------------------------------------------------------------------- void blend_hline(int x, int y, unsigned len, const color_type& c, int8u cover) { int16u* p = (int16u*)(m_rbuf->row(y)) + x; int alpha = int(cover) * c.a; if(alpha == 255*255) { int16u v = rgb555(c.r, c.g, c.b); do { *p++ = v; } while(--len); } else { do { int16u rgb = *p; int r = (rgb >> 7) & 0xF8; int g = (rgb >> 2) & 0xF8; int b = (rgb << 3) & 0xF8; *p++ = (int16u) ((((((c.r - r) * alpha) + (r << 16)) >> 9) & 0x7C00) | (((((c.g - g) * alpha) + (g << 16)) >> 14) & 0x3E0) | ((((c.b - b) * alpha) + (b << 16)) >> 19)); } while(--len); } } //-------------------------------------------------------------------- void blend_vline(int x, int y, unsigned len, const color_type& c, int8u cover) { int8u* p = m_rbuf->row(y) + (x << 1); int alpha = int(cover) * c.a; if(alpha == 255*255) { int16u v = rgb555(c.r, c.g, c.b); do { *(int16u*)p = v; p += m_rbuf->stride(); } while(--len); } else { do { int16u rgb = *(int16u*)p; int r = (rgb >> 7) & 0xF8; int g = (rgb >> 2) & 0xF8; int b = (rgb << 3) & 0xF8; *(int16u*)p = (int16u) ((((((c.r - r) * alpha) + (r << 16)) >> 9) & 0x7C00) | (((((c.g - g) * alpha) + (g << 16)) >> 14) & 0x3E0) | ((((c.b - b) * alpha) + (b << 16)) >> 19)); p += m_rbuf->stride(); } while(--len); } } //-------------------------------------------------------------------- void copy_from(const rendering_buffer& from, int xdst, int ydst, int xsrc, int ysrc, unsigned len) { memmove(m_rbuf->row(ydst) + xdst * 2, (const void*)(from.row(ysrc) + xsrc * 2), len * 2); } //-------------------------------------------------------------------- void blend_solid_hspan(int x, int y, unsigned len, const color_type& c, const int8u* covers) { int16u* p = (int16u*)(m_rbuf->row(y)) + x; do { int alpha = int(*covers++) * c.a; if(alpha) { if(alpha == 255*255) { *p = rgb555(c.r, c.g, c.b); } else { int16u rgb = *p; int r = (rgb >> 7) & 0xF8; int g = (rgb >> 2) & 0xF8; int b = (rgb << 3) & 0xF8; *p = (int16u) ((((((c.r - r) * alpha) + (r << 16)) >> 9) & 0x7C00) | (((((c.g - g) * alpha) + (g << 16)) >> 14) & 0x3E0) | ((((c.b - b) * alpha) + (b << 16)) >> 19)); } } ++p; } while(--len); } //-------------------------------------------------------------------- void blend_solid_vspan(int x, int y, unsigned len, const color_type& c, const int8u* covers) { int8u* p = m_rbuf->row(y) + (x << 1); do { int alpha = int(*covers++) * c.a; if(alpha) { if(alpha == 255*255) { *(int16u*)p = rgb555(c.r, c.g, c.b); } else { int16u rgb = *(int16u*)p; int r = (rgb >> 7) & 0xF8; int g = (rgb >> 2) & 0xF8; int b = (rgb << 3) & 0xF8; *(int16u*)p = (int16u) ((((((c.r - r) * alpha) + (r << 16)) >> 9) & 0x7C00) | (((((c.g - g) * alpha) + (g << 16)) >> 14) & 0x3E0) | ((((c.b - b) * alpha) + (b << 16)) >> 19)); } } p += m_rbuf->stride(); } while(--len); } //-------------------------------------------------------------------- void blend_color_hspan(int x, int y, unsigned len, const color_type* colors, const int8u* covers, int8u cover) { int16u* p = (int16u*)(m_rbuf->row(y)) + x; do { int alpha = colors->a * (covers ? int(*covers++) : int(cover)); if(alpha) { if(alpha == 255*255) { *(int16u*)p = rgb555(colors->r, colors->g, colors->b); } else { int16u rgb = *p; int r = (rgb >> 7) & 0xF8; int g = (rgb >> 2) & 0xF8; int b = (rgb << 3) & 0xF8; *(int16u*)p = (int16u) ((((((colors->r - r) * alpha) + (r << 16)) >> 9) & 0x7C00) | (((((colors->g - g) * alpha) + (g << 16)) >> 14) & 0x3E0) | ((((colors->b - b) * alpha) + (b << 16)) >> 19)); } } ++p; ++colors; } while(--len); } //-------------------------------------------------------------------- void blend_color_vspan(int x, int y, unsigned len, const color_type* colors, const int8u* covers, int8u cover) { int8u* p = m_rbuf->row(y) + (x << 1); do { int alpha = colors->a * (covers ? int(*covers++) : int(cover)); if(alpha) { if(alpha == 255*255) { *(int16u*)p = rgb555(colors->r, colors->g, colors->b); } else { int16u rgb = *(int16u*)p; int r = (rgb >> 7) & 0xF8; int g = (rgb >> 2) & 0xF8; int b = (rgb << 3) & 0xF8; *(int16u*)p = (int16u) ((((((colors->r - r) * alpha) + (r << 16)) >> 9) & 0x7C00) | (((((colors->g - g) * alpha) + (g << 16)) >> 14) & 0x3E0) | ((((colors->b - b) * alpha) + (b << 16)) >> 19)); } } p += m_rbuf->stride(); ++colors; } while(--len); } private: rendering_buffer* m_rbuf; }; } #endif aggdraw-1.3.14/agg2/include/agg_pixfmt_rgb565.h000066400000000000000000000267331417726601400210720ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_PIXFMT_RGB565_INCLUDED #define AGG_PIXFMT_RGB565_INCLUDED #include #include "agg_basics.h" #include "agg_color_rgba8.h" #include "agg_rendering_buffer.h" namespace agg { //------------------------------------------------------------------rgb565 inline int16u rgb565(unsigned r, unsigned g, unsigned b) { return (int16u)(((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3)); } //===========================================================pixfmt_rgb565 class pixfmt_rgb565 { public: typedef rgba8 color_type; //-------------------------------------------------------------------- pixfmt_rgb565(rendering_buffer& rb) : m_rbuf(&rb) { } //-------------------------------------------------------------------- unsigned width() const { return m_rbuf->width(); } unsigned height() const { return m_rbuf->height(); } //-------------------------------------------------------------------- color_type pixel(int x, int y) { unsigned rgb = ((int16u*)(m_rbuf->row(y)))[x]; return color_type((rgb >> 8) & 0xF8, (rgb >> 3) & 0xFC, (rgb << 3) & 0xF8); } //-------------------------------------------------------------------- void copy_pixel(int x, int y, const color_type& c) { ((int16u*)(m_rbuf->row(y)))[x] = rgb565(c.r, c.g, c.b); } //-------------------------------------------------------------------- void blend_pixel(int x, int y, const color_type& c, int8u cover) { int alpha = int(cover) * c.a; int16u* p = (int16u*)(m_rbuf->row(y)) + x; if(alpha == 255*255) { *p = rgb565(c.r, c.g, c.b); } else { int16u rgb = *p; int r = (rgb >> 8) & 0xF8; int g = (rgb >> 3) & 0xFC; int b = (rgb << 3) & 0xF8; *p = (int16u) ((((((c.r - r) * alpha) + (r << 16)) >> 8) & 0xF800) | (((((c.g - g) * alpha) + (g << 16)) >> 13) & 0x7E0) | ((((c.b - b) * alpha) + (b << 16)) >> 19)); } } //-------------------------------------------------------------------- void copy_hline(int x, int y, unsigned len, const color_type& c) { int16u* p = (int16u*)(m_rbuf->row(y)) + x; int16u v = rgb565(c.r, c.g, c.b); do { *p++ = v; } while(--len); } //-------------------------------------------------------------------- void copy_vline(int x, int y, unsigned len, const color_type& c) { int8u* p = m_rbuf->row(y) + (x << 1); int16u v = rgb565(c.r, c.g, c.b); do { *(int16u*)p = v; p += m_rbuf->stride(); } while(--len); } //-------------------------------------------------------------------- void blend_hline(int x, int y, unsigned len, const color_type& c, int8u cover) { int16u* p = (int16u*)(m_rbuf->row(y)) + x; int alpha = int(cover) * c.a; if(alpha == 255*255) { int16u v = rgb565(c.r, c.g, c.b); do { *p++ = v; } while(--len); } else { do { int16u rgb = *p; int r = (rgb >> 8) & 0xF8; int g = (rgb >> 3) & 0xFC; int b = (rgb << 3) & 0xF8; *p++ = (int16u) ((((((c.r - r) * alpha) + (r << 16)) >> 8) & 0xF800) | (((((c.g - g) * alpha) + (g << 16)) >> 13) & 0x7E0) | ((((c.b - b) * alpha) + (b << 16)) >> 19)); } while(--len); } } //-------------------------------------------------------------------- void blend_vline(int x, int y, unsigned len, const color_type& c, int8u cover) { int8u* p = m_rbuf->row(y) + (x << 1); int alpha = int(cover) * c.a; if(alpha == 255*255) { int16u v = rgb565(c.r, c.g, c.b); do { *(int16u*)p = v; p += m_rbuf->stride(); } while(--len); } else { do { int16u rgb = *(int16u*)p; int r = (rgb >> 8) & 0xF8; int g = (rgb >> 3) & 0xFC; int b = (rgb << 3) & 0xF8; *(int16u*)p = (int16u) ((((((c.r - r) * alpha) + (r << 16)) >> 8) & 0xF800) | (((((c.g - g) * alpha) + (g << 16)) >> 13) & 0x7E0) | ((((c.b - b) * alpha) + (b << 16)) >> 19)); p += m_rbuf->stride(); } while(--len); } } //-------------------------------------------------------------------- void copy_from(const rendering_buffer& from, int xdst, int ydst, int xsrc, int ysrc, unsigned len) { memmove(m_rbuf->row(ydst) + xdst * 2, (const void*)(from.row(ysrc) + xsrc * 2), len * 2); } //-------------------------------------------------------------------- void blend_solid_hspan(int x, int y, unsigned len, const color_type& c, const int8u* covers) { int16u* p = (int16u*)(m_rbuf->row(y)) + x; do { int alpha = int(*covers++) * c.a; if(alpha) { if(alpha == 255*255) { *p = rgb565(c.r, c.g, c.b); } else { int16u rgb = *p; int r = (rgb >> 8) & 0xF8; int g = (rgb >> 3) & 0xFC; int b = (rgb << 3) & 0xF8; *p = (int16u) ((((((c.r - r) * alpha) + (r << 16)) >> 8) & 0xF800) | (((((c.g - g) * alpha) + (g << 16)) >> 13) & 0x7E0) | ((((c.b - b) * alpha) + (b << 16)) >> 19)); } } ++p; } while(--len); } //-------------------------------------------------------------------- void blend_solid_vspan(int x, int y, unsigned len, const color_type& c, const int8u* covers) { int8u* p = m_rbuf->row(y) + (x << 1); do { int alpha = int(*covers++) * c.a; if(alpha) { if(alpha == 255*255) { *(int16u*)p = rgb565(c.r, c.g, c.b); } else { int16u rgb = *(int16u*)p; int r = (rgb >> 8) & 0xF8; int g = (rgb >> 3) & 0xFC; int b = (rgb << 3) & 0xF8; *(int16u*)p = (int16u) ((((((c.r - r) * alpha) + (r << 16)) >> 8) & 0xF800) | (((((c.g - g) * alpha) + (g << 16)) >> 13) & 0x7E0) | ((((c.b - b) * alpha) + (b << 16)) >> 19)); } } p += m_rbuf->stride(); } while(--len); } //-------------------------------------------------------------------- void blend_color_hspan(int x, int y, unsigned len, const color_type* colors, const int8u* covers, int8u cover) { int16u* p = (int16u*)(m_rbuf->row(y)) + x; do { int alpha = colors->a * (covers ? int(*covers++) : int(cover)); if(alpha) { if(alpha == 255*255) { *(int16u*)p = rgb565(colors->r, colors->g, colors->b); } else { int16u rgb = *p; int r = (rgb >> 8) & 0xF8; int g = (rgb >> 3) & 0xFC; int b = (rgb << 3) & 0xF8; *p = (int16u) ((((((colors->r - r) * alpha) + (r << 16)) >> 8) & 0xF800) | (((((colors->g - g) * alpha) + (g << 16)) >> 13) & 0x7E0) | ((((colors->b - b) * alpha) + (b << 16)) >> 19)); } } ++p; ++colors; } while(--len); } //-------------------------------------------------------------------- void blend_color_vspan(int x, int y, unsigned len, const color_type* colors, const int8u* covers, int8u cover) { int8u* p = m_rbuf->row(y) + (x << 1); do { int alpha = colors->a * (covers ? int(*covers++) : int(cover)); if(alpha) { if(alpha == 255*255) { *(int16u*)p = rgb565(colors->r, colors->g, colors->b); } else { int16u rgb = *(int16u*)p; int r = (rgb >> 8) & 0xF8; int g = (rgb >> 3) & 0xFC; int b = (rgb << 3) & 0xF8; *(int16u*)p = (int16u) ((((((colors->r - r) * alpha) + (r << 16)) >> 8) & 0xF800) | (((((colors->g - g) * alpha) + (g << 16)) >> 13) & 0x7E0) | ((((colors->b - b) * alpha) + (b << 16)) >> 19)); } } p += m_rbuf->stride(); ++colors; } while(--len); } private: rendering_buffer* m_rbuf; }; } #endif aggdraw-1.3.14/agg2/include/agg_pixfmt_rgba32.h000066400000000000000000000330761417726601400211360ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_PIXFMT_RGBA32_INCLUDED #define AGG_PIXFMT_RGBA32_INCLUDED #include #include "agg_basics.h" #include "agg_color_rgba8.h" #include "agg_rendering_buffer.h" namespace agg { //====================================================pixel_formats_rgba32 template class pixel_formats_rgba32 { public: typedef rgba8 color_type; //-------------------------------------------------------------------- pixel_formats_rgba32(rendering_buffer& rb) : m_rbuf(&rb) { } //-------------------------------------------------------------------- unsigned width() const { return m_rbuf->width(); } unsigned height() const { return m_rbuf->height(); } //-------------------------------------------------------------------- color_type pixel(int x, int y) { int8u* p = m_rbuf->row(y) + (x << 2); return color_type(p[Order::R], p[Order::G], p[Order::B], p[Order::A]); } //-------------------------------------------------------------------- void copy_pixel(int x, int y, const color_type& c) { int8u* p = m_rbuf->row(y) + (x << 2); p[Order::R] = (int8u)c.r; p[Order::G] = (int8u)c.g; p[Order::B] = (int8u)c.b; p[Order::A] = (int8u)c.a; } //-------------------------------------------------------------------- void blend_pixel(int x, int y, const color_type& c, int8u cover) { int8u* p = m_rbuf->row(y) + (x << 2); int alpha = int(cover) * int(c.a); if(alpha == 255*255) { p[Order::R] = (int8u)c.r; p[Order::G] = (int8u)c.g; p[Order::B] = (int8u)c.b; p[Order::A] = (int8u)c.a; } else { int r = p[Order::R]; int g = p[Order::G]; int b = p[Order::B]; int a = p[Order::A]; p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16); p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16); p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16); p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8); } } //-------------------------------------------------------------------- void copy_hline(int x, int y, unsigned len, const color_type& c) { int32u v; int8u* p8 = (int8u*)&v; p8[Order::R] = (int8u)c.r; p8[Order::G] = (int8u)c.g; p8[Order::B] = (int8u)c.b; p8[Order::A] = (int8u)c.a; int32u* p32 = (int32u*)(m_rbuf->row(y)) + x; do { *p32++ = v; } while(--len); } //-------------------------------------------------------------------- void copy_vline(int x, int y, unsigned len, const color_type& c) { int32u v; int8u* p8 = (int8u*)&v; p8[Order::R] = (int8u)c.r; p8[Order::G] = (int8u)c.g; p8[Order::B] = (int8u)c.b; p8[Order::A] = (int8u)c.a; int8u* p = m_rbuf->row(y) + (x << 2); do { *(int32u*)p = v; p += m_rbuf->stride(); } while(--len); } //-------------------------------------------------------------------- void blend_hline(int x, int y, unsigned len, const color_type& c, int8u cover) { int alpha = int(cover) * int(c.a); if(alpha == 255*255) { int32u v; int8u* p8 = (int8u*)&v; p8[Order::R] = (int8u)c.r; p8[Order::G] = (int8u)c.g; p8[Order::B] = (int8u)c.b; p8[Order::A] = (int8u)c.a; int32u* p32 = (int32u*)(m_rbuf->row(y)) + x; do { *p32++ = v; } while(--len); } else { int8u* p = m_rbuf->row(y) + (x << 2); do { int r = p[Order::R]; int g = p[Order::G]; int b = p[Order::B]; int a = p[Order::A]; p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16); p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16); p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16); p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8); p += 4; } while(--len); } } //-------------------------------------------------------------------- void blend_vline(int x, int y, unsigned len, const color_type& c, int8u cover) { int8u* p = m_rbuf->row(y) + (x << 2); int alpha = int(cover) * c.a; if(alpha == 255*255) { int32u v; int8u* p8 = (int8u*)&v; p8[Order::R] = (int8u)c.r; p8[Order::G] = (int8u)c.g; p8[Order::B] = (int8u)c.b; p8[Order::A] = (int8u)c.a; do { *(int32u*)p = v; p += m_rbuf->stride(); } while(--len); } else { do { int r = p[Order::R]; int g = p[Order::G]; int b = p[Order::B]; int a = p[Order::A]; p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16); p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16); p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16); p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8); p += m_rbuf->stride(); } while(--len); } } //-------------------------------------------------------------------- void copy_from(const rendering_buffer& from, int xdst, int ydst, int xsrc, int ysrc, unsigned len) { memmove(m_rbuf->row(ydst) + xdst * 4, (const void*)(from.row(ysrc) + xsrc * 4), len * 4); } //-------------------------------------------------------------------- void blend_solid_hspan(int x, int y, unsigned len, const color_type& c, const int8u* covers) { int8u* p = m_rbuf->row(y) + (x << 2); do { int alpha = int(*covers++) * c.a; if(alpha) { if(alpha == 255*255) { p[Order::R] = (int8u)c.r; p[Order::G] = (int8u)c.g; p[Order::B] = (int8u)c.b; p[Order::A] = (int8u)c.a; } else { int r = p[Order::R]; int g = p[Order::G]; int b = p[Order::B]; int a = p[Order::A]; p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16); p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16); p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16); p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8); } } p += 4; } while(--len); } //-------------------------------------------------------------------- void blend_solid_vspan(int x, int y, unsigned len, const color_type& c, const int8u* covers) { int8u* p = m_rbuf->row(y) + (x << 2); do { int alpha = int(*covers++) * c.a; if(alpha) { if(alpha == 255*255) { p[Order::R] = (int8u)c.r; p[Order::G] = (int8u)c.g; p[Order::B] = (int8u)c.b; p[Order::A] = (int8u)c.a; } else { int r = p[Order::R]; int g = p[Order::G]; int b = p[Order::B]; int a = p[Order::A]; p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16); p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16); p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16); p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8); } } p += m_rbuf->stride(); } while(--len); } //-------------------------------------------------------------------- void blend_color_hspan(int x, int y, unsigned len, const color_type* colors, const int8u* covers, int8u cover) { int8u* p = m_rbuf->row(y) + (x << 2); do { int alpha = colors->a * (covers ? int(*covers++) : int(cover)); if(alpha) { if(alpha == 255*255) { p[Order::R] = (int8u)colors->r; p[Order::G] = (int8u)colors->g; p[Order::B] = (int8u)colors->b; p[Order::A] = (int8u)colors->a; } else { int r = p[Order::R]; int g = p[Order::G]; int b = p[Order::B]; int a = p[Order::A]; p[Order::R] = (int8u)((((colors->r - r) * alpha) + (r << 16)) >> 16); p[Order::G] = (int8u)((((colors->g - g) * alpha) + (g << 16)) >> 16); p[Order::B] = (int8u)((((colors->b - b) * alpha) + (b << 16)) >> 16); p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8); } } p += 4; ++colors; } while(--len); } //-------------------------------------------------------------------- void blend_color_vspan(int x, int y, unsigned len, const color_type* colors, const int8u* covers, int8u cover) { int8u* p = m_rbuf->row(y) + (x << 2); do { int alpha = colors->a * (covers ? int(*covers++) : int(cover)); if(alpha) { if(alpha == 255*255) { p[Order::R] = (int8u)colors->r; p[Order::G] = (int8u)colors->g; p[Order::B] = (int8u)colors->b; p[Order::A] = (int8u)colors->a; } else { int r = p[Order::R]; int g = p[Order::G]; int b = p[Order::B]; int a = p[Order::A]; p[Order::R] = (int8u)((((colors->r - r) * alpha) + (r << 16)) >> 16); p[Order::G] = (int8u)((((colors->g - g) * alpha) + (g << 16)) >> 16); p[Order::B] = (int8u)((((colors->b - b) * alpha) + (b << 16)) >> 16); p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8); } } p += m_rbuf->stride(); ++colors; } while(--len); } private: rendering_buffer* m_rbuf; }; typedef pixel_formats_rgba32 pixfmt_rgba32; //----pixfmt_rgba32 typedef pixel_formats_rgba32 pixfmt_argb32; //----pixfmt_argb32 typedef pixel_formats_rgba32 pixfmt_abgr32; //----pixfmt_abgr32 typedef pixel_formats_rgba32 pixfmt_bgra32; //----pixfmt_bgra32 } #endif aggdraw-1.3.14/agg2/include/agg_pixfmt_rgba32_plain.h000066400000000000000000000245261417726601400223210ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_PIXFMT_RGBA32_PLAIN_INCLUDED #define AGG_PIXFMT_RGBA32_PLAIN_INCLUDED #include #include "agg_basics.h" #include "agg_color_rgba8.h" #include "agg_rendering_buffer.h" namespace agg { //===============================================pixel_formats_rgba32_plain template class pixel_formats_rgba32_plain { public: typedef rgba8 color_type; private: //-------------------------------------------------------------------- static inline void copy_pix(int8u* p, const color_type& c) { p[Order::R] = (int8u)c.r; p[Order::G] = (int8u)c.g; p[Order::B] = (int8u)c.b; p[Order::A] = (int8u)c.a; } //-------------------------------------------------------------------- static inline void blend_pix(int8u* p, const color_type& c, unsigned alpha) { int a = p[Order::A]; int r = p[Order::R] * a; int g = p[Order::G] * a; int b = p[Order::B] * a; a = ((alpha << 8) + (a << 16)) - alpha * a; p[Order::A] = (int8u)(a >> 16); p[Order::R] = (int8u)((((((c.r << 8) - r) * alpha) + (r << 16)) / a)); p[Order::G] = (int8u)((((((c.g << 8) - g) * alpha) + (g << 16)) / a)); p[Order::B] = (int8u)((((((c.b << 8) - b) * alpha) + (b << 16)) / a)); } //-------------------------------------------------------------------- static inline void copy_or_blend_pix(int8u* p, const color_type& c, unsigned cover) { unsigned alpha = cover * c.a; // For testing //color_type c2 = c; //c2.a = alpha >> 8; //copy_or_blend_pix(p, c2); if(alpha) { if(alpha == 255*255) { copy_pix(p, c); } else { blend_pix(p, c, alpha); } } } //-------------------------------------------------------------------- static inline void copy_or_blend_pix(int8u* p, const color_type& c) { unsigned alpha = c.a; if(alpha) { if(alpha == 255) { copy_pix(p, c); } else { int a = p[Order::A]; int r = p[Order::R] * a; int g = p[Order::G] * a; int b = p[Order::B] * a; a = ((alpha + a) << 8) - alpha * a; p[Order::A] = (int8u)(a >> 8); p[Order::R] = (int8u)((((((c.r << 8) - r) * alpha) + (r << 8)) / a)); p[Order::G] = (int8u)((((((c.g << 8) - g) * alpha) + (g << 8)) / a)); p[Order::B] = (int8u)((((((c.b << 8) - b) * alpha) + (b << 8)) / a)); } } } public: //-------------------------------------------------------------------- pixel_formats_rgba32_plain(rendering_buffer& rb) : m_rbuf(&rb) { } //-------------------------------------------------------------------- unsigned width() const { return m_rbuf->width(); } unsigned height() const { return m_rbuf->height(); } //-------------------------------------------------------------------- color_type pixel(int x, int y) { int8u* p = m_rbuf->row(y) + (x << 2); return color_type(p[Order::R], p[Order::G], p[Order::B], p[Order::A]); } //-------------------------------------------------------------------- void copy_pixel(int x, int y, const color_type& c) { int8u* p = m_rbuf->row(y) + (x << 2); p[Order::R] = (int8u)c.r; p[Order::G] = (int8u)c.g; p[Order::B] = (int8u)c.b; p[Order::A] = (int8u)c.a; } //-------------------------------------------------------------------- void blend_pixel(int x, int y, const color_type& c, int8u cover) { copy_or_blend_pix(m_rbuf->row(y) + (x << 2), c, cover); } //-------------------------------------------------------------------- void copy_hline(int x, int y, unsigned len, const color_type& c) { int32u v; copy_pix((int8u*)&v, c); int32u* p32 = (int32u*)(m_rbuf->row(y)) + x; do { *p32++ = v; } while(--len); } //-------------------------------------------------------------------- void copy_vline(int x, int y, unsigned len, const color_type& c) { int32u v; copy_pix((int8u*)&v, c); int8u* p = m_rbuf->row(y) + (x << 2); do { *(int32u*)p = v; p += m_rbuf->stride(); } while(--len); } //-------------------------------------------------------------------- void blend_hline(int x, int y, unsigned len, const color_type& c, int8u cover) { unsigned alpha = unsigned(cover) * c.a; if(alpha) { if(alpha == 255*255) { int32u v; copy_pix((int8u*)&v, c); int32u* p32 = (int32u*)(m_rbuf->row(y)) + x; do { *p32++ = v; } while(--len); } else { int8u* p = m_rbuf->row(y) + (x << 2); do { blend_pix(p, c, alpha); p += 4; } while(--len); } } } //-------------------------------------------------------------------- void blend_vline(int x, int y, unsigned len, const color_type& c, int8u cover) { int8u* p = m_rbuf->row(y) + (x << 2); unsigned alpha = unsigned(cover) * c.a; if(alpha) { unsigned alpha = unsigned(cover) * c.a; if(alpha == 255*255) { int32u v; copy_pix((int8u*)&v, c); do { *(int32u*)p = v; p += m_rbuf->stride(); } while(--len); } else { do { blend_pix(p, c, alpha); p += m_rbuf->stride(); } while(--len); } } } //-------------------------------------------------------------------- void copy_from(const rendering_buffer& from, int xdst, int ydst, int xsrc, int ysrc, unsigned len) { memmove(m_rbuf->row(ydst) + xdst * 4, (const void*)(from.row(ysrc) + xsrc * 4), len * 4); } //-------------------------------------------------------------------- void blend_solid_hspan(int x, int y, unsigned len, const color_type& c, const int8u* covers) { int8u* p = m_rbuf->row(y) + (x << 2); do { copy_or_blend_pix(p, c, *covers++); p += 4; } while(--len); } //-------------------------------------------------------------------- void blend_solid_vspan(int x, int y, unsigned len, const color_type& c, const int8u* covers) { int8u* p = m_rbuf->row(y) + (x << 2); do { copy_or_blend_pix(p, c, *covers++); p += m_rbuf->stride(); } while(--len); } //-------------------------------------------------------------------- void blend_color_hspan(int x, int y, unsigned len, const color_type* colors, const int8u* covers, int8u cover) { int8u* p = m_rbuf->row(y) + (x << 2); do { copy_or_blend_pix(p, *colors++, covers ? *covers++ : cover); p += 4; } while(--len); } //-------------------------------------------------------------------- void blend_color_vspan(int x, int y, unsigned len, const color_type* colors, const int8u* covers, int8u cover) { int8u* p = m_rbuf->row(y) + (x << 2); do { copy_or_blend_pix(p, *colors++, covers ? *covers++ : cover); p += m_rbuf->stride(); } while(--len); } private: rendering_buffer* m_rbuf; }; typedef pixel_formats_rgba32_plain pixfmt_rgba32_plain; //----pixfmt_rgba32_plain typedef pixel_formats_rgba32_plain pixfmt_argb32_plain; //----pixfmt_argb32_plain typedef pixel_formats_rgba32_plain pixfmt_abgr32_plain; //----pixfmt_abgr32_plain typedef pixel_formats_rgba32_plain pixfmt_bgra32_plain; //----pixfmt_bgra32_plain } #endif aggdraw-1.3.14/agg2/include/agg_pixfmt_rgba32_pre.h000066400000000000000000000233531417726601400220010ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_PIXFMT_RGBA32_PRE_INCLUDED #define AGG_PIXFMT_RGBA32_PRE_INCLUDED #include #include "agg_basics.h" #include "agg_color_rgba8.h" #include "agg_rendering_buffer.h" namespace agg { //=================================================pixel_formats_rgba32_pre template class pixel_formats_rgba32_pre { public: typedef rgba8 color_type; private: //-------------------------------------------------------------------- static inline void copy_pix(int8u* p, const color_type& c) { p[Order::R] = (int8u)c.r; p[Order::G] = (int8u)c.g; p[Order::B] = (int8u)c.b; p[Order::A] = (int8u)c.a; } //-------------------------------------------------------------------- static inline void blend_pix(int8u* p, const color_type& c, unsigned cover, unsigned alpha) { p[Order::R] = (int8u)((p[Order::R] * alpha + ((c.r * cover) << 8)) >> 16); p[Order::G] = (int8u)((p[Order::G] * alpha + ((c.g * cover) << 8)) >> 16); p[Order::B] = (int8u)((p[Order::B] * alpha + ((c.b * cover) << 8)) >> 16); p[Order::A] = (int8u)(255 - ((alpha * (255 - p[Order::A])) >> 16)); } //-------------------------------------------------------------------- static inline void copy_or_blend_pix(int8u* p, const color_type& c, unsigned cover) { unsigned alpha = 65535 - cover * c.a; if(alpha < 65535) { if(alpha <= 65535-255*255) { copy_pix(p, c); } else { blend_pix(p, c, cover, alpha); } } } //-------------------------------------------------------------------- static inline void copy_or_blend_pix(int8u* p, const color_type& c) { unsigned alpha = 255 - c.a; if(alpha < 255) { if(alpha == 0) { copy_pix(p, c); } else { p[Order::R] = (int8u)((p[Order::R] * alpha + (c.r << 8)) >> 8); p[Order::G] = (int8u)((p[Order::G] * alpha + (c.g << 8)) >> 8); p[Order::B] = (int8u)((p[Order::B] * alpha + (c.b << 8)) >> 8); p[Order::A] = (int8u)(255 - ((alpha * (255 - p[Order::A])) >> 8)); } } } public: //-------------------------------------------------------------------- pixel_formats_rgba32_pre(rendering_buffer& rb) : m_rbuf(&rb) { } //-------------------------------------------------------------------- unsigned width() const { return m_rbuf->width(); } unsigned height() const { return m_rbuf->height(); } //-------------------------------------------------------------------- color_type pixel(int x, int y) { int8u* p = m_rbuf->row(y) + (x << 2); return color_type(p[Order::R], p[Order::G], p[Order::B], p[Order::A]); } //-------------------------------------------------------------------- void copy_pixel(int x, int y, const color_type& c) { int8u* p = m_rbuf->row(y) + (x << 2); p[Order::R] = (int8u)c.r; p[Order::G] = (int8u)c.g; p[Order::B] = (int8u)c.b; p[Order::A] = (int8u)c.a; } //-------------------------------------------------------------------- void blend_pixel(int x, int y, const color_type& c, int8u cover) { copy_or_blend_pix(m_rbuf->row(y) + (x << 2), c, cover); } //-------------------------------------------------------------------- void copy_hline(int x, int y, unsigned len, const color_type& c) { int32u v; copy_pix((int8u*)&v, c); int32u* p32 = (int32u*)(m_rbuf->row(y)) + x; do { *p32++ = v; } while(--len); } //-------------------------------------------------------------------- void copy_vline(int x, int y, unsigned len, const color_type& c) { int32u v; copy_pix((int8u*)&v, c); int8u* p = m_rbuf->row(y) + (x << 2); do { *(int32u*)p = v; p += m_rbuf->stride(); } while(--len); } //-------------------------------------------------------------------- void blend_hline(int x, int y, unsigned len, const color_type& c, int8u cover) { unsigned alpha = unsigned(cover) * c.a; if(alpha == 255*255) { int32u v; copy_pix((int8u*)&v, c); int32u* p32 = (int32u*)(m_rbuf->row(y)) + x; do { *p32++ = v; } while(--len); } else { int8u* p = m_rbuf->row(y) + (x << 2); alpha = 65535 - alpha; do { blend_pix(p, c, cover, alpha); p += 4; } while(--len); } } //-------------------------------------------------------------------- void blend_vline(int x, int y, unsigned len, const color_type& c, int8u cover) { int8u* p = m_rbuf->row(y) + (x << 2); unsigned alpha = unsigned(cover) * c.a; if(alpha == 255*255) { int32u v; copy_pix((int8u*)&v, c); do { *(int32u*)p = v; p += m_rbuf->stride(); } while(--len); } else { alpha = 65535 - alpha; do { blend_pix(p, c, cover, alpha); p += m_rbuf->stride(); } while(--len); } } //-------------------------------------------------------------------- void copy_from(const rendering_buffer& from, int xdst, int ydst, int xsrc, int ysrc, unsigned len) { memmove(m_rbuf->row(ydst) + xdst * 4, (const void*)(from.row(ysrc) + xsrc * 4), len * 4); } //-------------------------------------------------------------------- void blend_solid_hspan(int x, int y, unsigned len, const color_type& c, const int8u* covers) { int8u* p = m_rbuf->row(y) + (x << 2); do { copy_or_blend_pix(p, c, *covers++); p += 4; } while(--len); } //-------------------------------------------------------------------- void blend_solid_vspan(int x, int y, unsigned len, const color_type& c, const int8u* covers) { int8u* p = m_rbuf->row(y) + (x << 2); do { copy_or_blend_pix(p, c, *covers++); p += m_rbuf->stride(); } while(--len); } //-------------------------------------------------------------------- void blend_color_hspan(int x, int y, unsigned len, const color_type* colors, const int8u* covers, int8u cover) { int8u* p = m_rbuf->row(y) + (x << 2); do { copy_or_blend_pix(p, *colors++, covers ? *covers++ : cover); p += 4; } while(--len); } //-------------------------------------------------------------------- void blend_color_vspan(int x, int y, unsigned len, const color_type* colors, const int8u* covers, int8u cover) { int8u* p = m_rbuf->row(y) + (x << 2); do { copy_or_blend_pix(p, *colors++, covers ? *covers++ : cover); p += m_rbuf->stride(); } while(--len); } private: rendering_buffer* m_rbuf; }; typedef pixel_formats_rgba32_pre pixfmt_rgba32_pre; //----pixfmt_rgba32_pre typedef pixel_formats_rgba32_pre pixfmt_argb32_pre; //----pixfmt_argb32_pre typedef pixel_formats_rgba32_pre pixfmt_abgr32_pre; //----pixfmt_abgr32_pre typedef pixel_formats_rgba32_pre pixfmt_bgra32_pre; //----pixfmt_bgra32_pre } #endif aggdraw-1.3.14/agg2/include/agg_rasterizer_outline.h000066400000000000000000000075501417726601400224160ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_RASTERIZER_OUTLINE_INCLUDED #define AGG_RASTERIZER_OUTLINE_INCLUDED #include "agg_basics.h" namespace agg { //======================================================rasterizer_outline template class rasterizer_outline { public: rasterizer_outline(Renderer& ren) : m_ren(&ren), m_start_x(0), m_start_y(0) { } //-------------------------------------------------------------------- void move_to(int x, int y) { m_ren->move_to(m_start_x = x, m_start_y = y); } //-------------------------------------------------------------------- void line_to(int x, int y) { m_ren->line_to(x, y); } //-------------------------------------------------------------------- void move_to_d(double x, double y) { move_to(m_ren->coord(x), m_ren->coord(y)); } //-------------------------------------------------------------------- void line_to_d(double x, double y) { line_to(m_ren->coord(x), m_ren->coord(y)); } //-------------------------------------------------------------------- void close() { line_to(m_start_x, m_start_y); } //-------------------------------------------------------------------- void add_vertex(double x, double y, unsigned cmd) { if(is_move_to(cmd)) { move_to_d(x, y); } else { if(is_end_poly(cmd)) { if(is_closed(cmd)) close(); } else { line_to_d(x, y); } } } //-------------------------------------------------------------------- template void add_path(VertexSource& vs, unsigned id=0) { double x; double y; unsigned cmd; vs.rewind(id); while(!is_stop(cmd = vs.vertex(&x, &y))) { add_vertex(x, y, cmd); } } //-------------------------------------------------------------------- template void render_all_paths(VertexSource& vs, const ColorStorage& colors, const PathId& id, unsigned num_paths) { for(unsigned i = 0; i < num_paths; i++) { m_ren->line_color(colors[i]); add_path(vs, id[i]); } } //-------------------------------------------------------------------- template void render_ctrl(Ctrl& c) { unsigned i; for(i = 0; i < c.num_paths(); i++) { m_ren->line_color(c.color(i)); add_path(c, i); } } private: Renderer* m_ren; int m_start_x; int m_start_y; }; } #endif aggdraw-1.3.14/agg2/include/agg_rasterizer_outline_aa.h000066400000000000000000000377661417726601400230730ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_RASTERIZER_OUTLINE_AA_INCLUDED #define AGG_RASTERIZER_OUTLINE_AA_INCLUDED #include "agg_basics.h" #include "agg_line_aa_basics.h" #include "agg_vertex_sequence.h" namespace agg { //------------------------------------------------------------------------- inline bool cmp_dist_start(int d) { return d > 0; } inline bool cmp_dist_end(int d) { return d <= 0; } //-----------------------------------------------------------line_aa_vertex // Vertex (x, y) with the distance to the next one. The last vertex has // the distance between the last and the first points struct line_aa_vertex { int x; int y; int len; line_aa_vertex() {} line_aa_vertex(int x_, int y_) : x(x_), y(y_), len(0) { } bool operator () (const line_aa_vertex& val) { double dx = val.x - x; double dy = val.y - y; return (len = int(sqrt(dx * dx + dy * dy))) > (line_subpixel_size + line_subpixel_size / 2); } }; //=======================================================rasterizer_outline_aa template class rasterizer_outline_aa { private: //------------------------------------------------------------------------ struct draw_vars { unsigned idx; int x1, y1, x2, y2; line_parameters curr, next; int lcurr, lnext; int xb1, yb1, xb2, yb2; unsigned flags; }; void draw(draw_vars& dv, unsigned start, unsigned end); public: typedef line_aa_vertex vertex_type; typedef vertex_sequence vertex_storage_type; rasterizer_outline_aa(Renderer& ren) : m_ren(ren), m_accurate_join(m_ren.accurate_join_only()), m_round_cap(false), m_start_x(0), m_start_y(0) { } //------------------------------------------------------------------------ void accurate_join(bool v) { m_accurate_join = m_ren.accurate_join_only() ? true : v; } bool accurate_join() const { return m_accurate_join; } //------------------------------------------------------------------------ void round_cap(bool v) { m_round_cap = v; } bool round_cap() const { return m_round_cap; } //------------------------------------------------------------------------ void move_to(int x, int y) { m_src_vertices.modify_last(vertex_type(m_start_x = x, m_start_y = y)); } //------------------------------------------------------------------------ void line_to(int x, int y) { m_src_vertices.add(vertex_type(x, y)); } //------------------------------------------------------------------------ void move_to_d(double x, double y) { move_to(line_coord(x), line_coord(y)); } //------------------------------------------------------------------------ void line_to_d(double x, double y) { line_to(line_coord(x), line_coord(y)); } //------------------------------------------------------------------------ void render(bool close_polygon); //------------------------------------------------------------------------ void add_vertex(double x, double y, unsigned cmd) { if(is_move_to(cmd)) { render(false); move_to_d(x, y); } else { if(is_end_poly(cmd)) { render(is_closed(cmd)); if(is_closed(cmd)) move_to(m_start_x, m_start_y); } else { line_to_d(x, y); } } } //------------------------------------------------------------------------ template void add_path(VertexSource& vs, unsigned id=0) { double x; double y; unsigned cmd; vs.rewind(id); while(!is_stop(cmd = vs.vertex(&x, &y))) { add_vertex(x, y, cmd); } render(false); } //------------------------------------------------------------------------ template void render_all_paths(VertexSource& vs, const ColorStorage& colors, const PathId& id, unsigned num_paths) { for(unsigned i = 0; i < num_paths; i++) { m_ren.color(colors[i]); add_path(vs, id[i]); } } //------------------------------------------------------------------------ template void render_ctrl(Ctrl& c) { unsigned i; for(i = 0; i < c.num_paths(); i++) { m_ren.color(c.color(i)); add_path(c, i); } } private: rasterizer_outline_aa(const rasterizer_outline_aa&); const rasterizer_outline_aa& operator = (const rasterizer_outline_aa&); Renderer& m_ren; vertex_storage_type m_src_vertices; bool m_accurate_join; bool m_round_cap; int m_start_x; int m_start_y; }; //---------------------------------------------------------------------------- template void rasterizer_outline_aa::draw(draw_vars& dv, unsigned start, unsigned end) { unsigned i; const vertex_storage_type::value_type* v; for(i = start; i < end; i++) { switch(dv.flags) { case 0: m_ren.line3(dv.curr, dv.xb1, dv.yb1, dv.xb2, dv.yb2); break; case 1: m_ren.line2(dv.curr, dv.xb2, dv.yb2); break; case 2: m_ren.line1(dv.curr, dv.xb1, dv.yb1); break; case 3: m_ren.line0(dv.curr); break; } dv.x1 = dv.x2; dv.y1 = dv.y2; dv.lcurr = dv.lnext; dv.lnext = m_src_vertices[dv.idx].len; ++dv.idx; if(dv.idx >= m_src_vertices.size()) dv.idx = 0; v = &m_src_vertices[dv.idx]; dv.x2 = v->x; dv.y2 = v->y; dv.curr = dv.next; dv.next = line_parameters(dv.x1, dv.y1, dv.x2, dv.y2, dv.lnext); dv.xb1 = dv.xb2; dv.yb1 = dv.yb2; if(m_accurate_join) { dv.flags = 0; } else { dv.flags >>= 1; dv.flags |= ((dv.curr.diagonal_quadrant() == dv.next.diagonal_quadrant()) << 1); } if((dv.flags & 2) == 0) { bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2); } } } //---------------------------------------------------------------------------- template void rasterizer_outline_aa::render(bool close_polygon) { m_src_vertices.close(close_polygon); draw_vars dv; const vertex_storage_type::value_type* v; int x1; int y1; int x2; int y2; int lprev; if(close_polygon) { if(m_src_vertices.size() >= 3) { dv.idx = 2; v = &m_src_vertices[m_src_vertices.size() - 1]; x1 = v->x; y1 = v->y; lprev = v->len; v = &m_src_vertices[0]; x2 = v->x; y2 = v->y; dv.lcurr = v->len; line_parameters prev(x1, y1, x2, y2, lprev); v = &m_src_vertices[1]; dv.x1 = v->x; dv.y1 = v->y; dv.lnext = v->len; dv.curr = line_parameters(x2, y2, dv.x1, dv.y1, dv.lcurr); v = &m_src_vertices[dv.idx]; dv.x2 = v->x; dv.y2 = v->y; dv.next = line_parameters(dv.x1, dv.y1, dv.x2, dv.y2, dv.lnext); dv.xb1 = 0; dv.yb1 = 0; dv.xb2 = 0; dv.yb2 = 0; if(m_accurate_join) { dv.flags = 0; } else { dv.flags = (prev.diagonal_quadrant() == dv.curr.diagonal_quadrant()) | ((dv.curr.diagonal_quadrant() == dv.next.diagonal_quadrant()) << 1); } if((dv.flags & 1) == 0) { bisectrix(prev, dv.curr, &dv.xb1, &dv.yb1); } if((dv.flags & 2) == 0) { bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2); } draw(dv, 0, m_src_vertices.size()); } } else { switch(m_src_vertices.size()) { case 0: case 1: break; case 2: { v = &m_src_vertices[0]; x1 = v->x; y1 = v->y; lprev = v->len; v = &m_src_vertices[1]; x2 = v->x; y2 = v->y; line_parameters lp(x1, y1, x2, y2, lprev); if(m_round_cap) { m_ren.semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1)); } m_ren.line3(lp, x1 + (y2 - y1), y1 - (x2 - x1), x2 + (y2 - y1), y2 - (x2 - x1)); if(m_round_cap) { m_ren.semidot(cmp_dist_end, x2, y2, x2 + (y2 - y1), y2 - (x2 - x1)); } } break; case 3: { int x3, y3; int lnext; v = &m_src_vertices[0]; x1 = v->x; y1 = v->y; lprev = v->len; v = &m_src_vertices[1]; x2 = v->x; y2 = v->y; lnext = v->len; v = &m_src_vertices[2]; x3 = v->x; y3 = v->y; line_parameters lp1(x1, y1, x2, y2, lprev); line_parameters lp2(x2, y2, x3, y3, lnext); bisectrix(lp1, lp2, &dv.xb1, &dv.yb1); if(m_round_cap) { m_ren.semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1)); } m_ren.line3(lp1, x1 + (y2 - y1), y1 - (x2 - x1), dv.xb1, dv.yb1); m_ren.line3(lp2, dv.xb1, dv.yb1, x3 + (y3 - y2), y3 - (x3 - x2)); if(m_round_cap) { m_ren.semidot(cmp_dist_end, x3, y3, x3 + (y3 - y2), y3 - (x3 - x2)); } } break; default: { dv.idx = 3; v = &m_src_vertices[0]; x1 = v->x; y1 = v->y; lprev = v->len; v = &m_src_vertices[1]; x2 = v->x; y2 = v->y; dv.lcurr = v->len; line_parameters prev(x1, y1, x2, y2, lprev); v = &m_src_vertices[2]; dv.x1 = v->x; dv.y1 = v->y; dv.lnext = v->len; dv.curr = line_parameters(x2, y2, dv.x1, dv.y1, dv.lcurr); v = &m_src_vertices[dv.idx]; dv.x2 = v->x; dv.y2 = v->y; dv.next = line_parameters(dv.x1, dv.y1, dv.x2, dv.y2, dv.lnext); dv.xb1 = 0; dv.yb1 = 0; dv.xb2 = 0; dv.yb2 = 0; if(m_accurate_join) { dv.flags = 0; } else { dv.flags = (prev.diagonal_quadrant() == dv.curr.diagonal_quadrant()) | ((dv.curr.diagonal_quadrant() == dv.next.diagonal_quadrant()) << 1); } if((dv.flags & 1) == 0) { bisectrix(prev, dv.curr, &dv.xb1, &dv.yb1); m_ren.line3(prev, x1 + (y2 - y1), y1 - (x2 - x1), dv.xb1, dv.yb1); } else { m_ren.line1(prev, x1 + (y2 - y1), y1 - (x2 - x1)); } if(m_round_cap) { m_ren.semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1)); } if((dv.flags & 2) == 0) { bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2); } draw(dv, 1, m_src_vertices.size() - 2); if((dv.flags & 1) == 0) { m_ren.line3(dv.curr, dv.xb1, dv.yb1, dv.curr.x2 + (dv.curr.y2 - dv.curr.y1), dv.curr.y2 - (dv.curr.x2 - dv.curr.x1)); } else { m_ren.line2(dv.curr, dv.curr.x2 + (dv.curr.y2 - dv.curr.y1), dv.curr.y2 - (dv.curr.x2 - dv.curr.x1)); } if(m_round_cap) { m_ren.semidot(cmp_dist_end, dv.curr.x2, dv.curr.y2, dv.curr.x2 + (dv.curr.y2 - dv.curr.y1), dv.curr.y2 - (dv.curr.x2 - dv.curr.x1)); } } break; } } m_src_vertices.remove_all(); } } #endif aggdraw-1.3.14/agg2/include/agg_rasterizer_scanline_aa.h000066400000000000000000000566231417726601400232010ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // // The author gratefully acknowleges the support of David Turner, // Robert Wilhelm, and Werner Lemberg - the authors of the FreeType // libray - in producing this work. See http://www.freetype.org for details. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Class rasterizer_scanline_aa // // //---------------------------------------------------------------------------- #ifndef AGG_RASTERIZER_SCANLINE_AA_INCLUDED #define AGG_RASTERIZER_SCANLINE_AA_INCLUDED #include #include #include "agg_basics.h" #include "agg_math.h" #include "agg_gamma_functions.h" #include "agg_clip_liang_barsky.h" #include "agg_render_scanlines.h" namespace agg { //------------------------------------------------------------------------ // These constants determine the subpixel accuracy, to be more precise, // the number of bits of the fractional part of the coordinates. // The possible coordinate capacity in bits can be calculated by formula: // sizeof(int) * 8 - poly_base_shift * 2, i.e, for 32-bit integers and // 8-bits fractional part the capacity is 16 bits or [-32768...32767]. enum { poly_base_shift = 8, //----poly_base_shift poly_base_size = 1 << poly_base_shift, //----poly_base_size poly_base_mask = poly_base_size - 1 //----poly_base_mask }; //--------------------------------------------------------------poly_coord inline int poly_coord(double c) { return int(c * poly_base_size); } //-----------------------------------------------------------------cell_aa // A pixel cell. There're no constructors defined and it was done // intentionally in order to avoid extra overhead when allocating an // array of cells. struct cell_aa { int16 x; int16 y; int packed_coord; int cover; int area; void set(int x, int y, int c, int a); void set_coord(int x, int y); void set_cover(int c, int a); void add_cover(int c, int a); }; //--------------------------------------------------------------outline_aa // An internal class that implements the main rasterization algorithm. // Used in the rasterizer. Should not be used direcly. class outline_aa { enum { cell_block_shift = 12, cell_block_size = 1 << cell_block_shift, cell_block_mask = cell_block_size - 1, cell_block_pool = 256, cell_block_limit = 1024 }; public: ~outline_aa(); outline_aa(); void reset(); void move_to(int x, int y); void line_to(int x, int y); int min_x() const { return m_min_x; } int min_y() const { return m_min_y; } int max_x() const { return m_max_x; } int max_y() const { return m_max_y; } const cell_aa* const* cells(); unsigned num_cells() { cells(); return m_num_cells; } bool sorted() const { return m_sorted; } private: outline_aa(const outline_aa&); const outline_aa& operator = (const outline_aa&); void set_cur_cell(int x, int y); void add_cur_cell(); void sort_cells(); void render_hline(int ey, int x1, int y1, int x2, int y2); void render_line(int x1, int y1, int x2, int y2); void allocate_block(); static void qsort_cells(cell_aa** start, unsigned num); private: unsigned m_num_blocks; unsigned m_max_blocks; unsigned m_cur_block; unsigned m_num_cells; cell_aa** m_cells; cell_aa* m_cur_cell_ptr; cell_aa** m_sorted_cells; unsigned m_sorted_size; cell_aa m_cur_cell; int m_cur_x; int m_cur_y; int m_min_x; int m_min_y; int m_max_x; int m_max_y; bool m_sorted; }; //----------------------------------------------------------filling_rule_e enum filling_rule_e { fill_non_zero, fill_even_odd }; //----------------------------------------------------------clipping_flags // Determine the clipping code of the vertex according to the // Cyrus-Beck line clipping algorithm // // | | // 0110 | 0010 | 0011 // | | // -------+--------+-------- clip_box.y2 // | | // 0100 | 0000 | 0001 // | | // -------+--------+-------- clip_box.y1 // | | // 1100 | 1000 | 1001 // | | // clip_box.x1 clip_box.x2 // // inline unsigned clipping_flags(int x, int y, const rect& clip_box) { return (x > clip_box.x2) | ((y > clip_box.y2) << 1) | ((x < clip_box.x1) << 2) | ((y < clip_box.y1) << 3); } //==================================================rasterizer_scanline_aa // Polygon rasterizer that is used to render filled polygons with // high-quality Anti-Aliasing. Internally, by default, the class uses // integer coordinates in format 24.8, i.e. 24 bits for integer part // and 8 bits for fractional - see poly_base_shift. This class can be // used in the following way: // // 1. filling_rule(filling_rule_e ft) - optional. // // 2. gamma() - optional. // // 3. reset() // // 4. move_to(x, y) / line_to(x, y) - make the polygon. One can create // more than one contour, but each contour must consist of at least 3 // vertices, i.e. move_to(x1, y1); line_to(x2, y2); line_to(x3, y3); // is the absolute minimum of vertices that define a triangle. // The algorithm does not check either the number of vertices nor // coincidence of their coordinates, but in the worst case it just // won't draw anything. // The orger of the vertices (clockwise or counterclockwise) // is important when using the non-zero filling rule (fill_non_zero). // In this case the vertex order of all the contours must be the same // if you want your intersecting polygons to be without "holes". // You actually can use different vertices order. If the contours do not // intersect each other the order is not important anyway. If they do, // contours with the same vertex order will be rendered without "holes" // while the intersecting contours with different orders will have "holes". // // filling_rule() and gamma() can be called anytime before "sweeping". //------------------------------------------------------------------------ template class rasterizer_scanline_aa { enum status { status_initial, status_line_to, status_closed }; struct iterator { const cell_aa* const* cells; int cover; int last_y; }; public: enum { aa_shift = AA_Shift, aa_num = 1 << aa_shift, aa_mask = aa_num - 1, aa_2num = aa_num * 2, aa_2mask = aa_2num - 1 }; //-------------------------------------------------------------------- rasterizer_scanline_aa() : m_filling_rule(fill_non_zero), m_clipped_start_x(0), m_clipped_start_y(0), m_start_x(0), m_start_y(0), m_prev_x(0), m_prev_y(0), m_prev_flags(0), m_status(status_initial), m_clipping(false) { int i; for(i = 0; i < aa_num; i++) m_gamma[i] = i; } //-------------------------------------------------------------------- template rasterizer_scanline_aa(const GammaF& gamma_function) : m_filling_rule(fill_non_zero), m_clipped_start_x(0), m_clipped_start_y(0), m_start_x(0), m_start_y(0), m_prev_x(0), m_prev_y(0), m_prev_flags(0), m_status(status_initial), m_clipping(false) { gamma(gamma_function); } //-------------------------------------------------------------------- void reset(); void filling_rule(filling_rule_e filling_rule); void clip_box(double x1, double y1, double x2, double y2); void reset_clipping(); //-------------------------------------------------------------------- template void gamma(const GammaF& gamma_function) { int i; for(i = 0; i < aa_num; i++) { m_gamma[i] = int(floor(gamma_function(double(i) / aa_mask) * aa_mask + 0.5)); } } //-------------------------------------------------------------------- unsigned apply_gamma(unsigned cover) const { return m_gamma[cover]; } //-------------------------------------------------------------------- void add_vertex(double x, double y, unsigned cmd); void move_to(int x, int y); void line_to(int x, int y); void close_polygon(); void move_to_d(double x, double y); void line_to_d(double x, double y); //-------------------------------------------------------------------- int min_x() const { return m_outline.min_x(); } int min_y() const { return m_outline.min_y(); } int max_x() const { return m_outline.max_x(); } int max_y() const { return m_outline.max_y(); } //-------------------------------------------------------------------- unsigned calculate_alpha(int area) const { int cover = area >> (poly_base_shift*2 + 1 - aa_shift); if(cover < 0) cover = -cover; if(m_filling_rule == fill_even_odd) { cover &= aa_2mask; if(cover > aa_num) { cover = aa_2num - cover; } } if(cover > aa_mask) cover = aa_mask; return m_gamma[cover]; } //-------------------------------------------------------------------- void sort() { m_outline.cells(); } //-------------------------------------------------------------------- bool rewind_scanlines() { close_polygon(); m_iterator.cells = m_outline.cells(); if(m_outline.num_cells() == 0) { return false; } m_iterator.cover = 0; m_iterator.last_y = (*m_iterator.cells)->y; return true; } //-------------------------------------------------------------------- template bool sweep_scanline(Scanline& sl) { sl.reset_spans(); for(;;) { const cell_aa* cur_cell = *m_iterator.cells; if(cur_cell == 0) return false; ++m_iterator.cells; m_iterator.last_y = cur_cell->y; for(;;) { int coord = cur_cell->packed_coord; int area = cur_cell->area; int last_x = cur_cell->x; m_iterator.cover += cur_cell->cover; //accumulate all cells with the same coordinates for(; (cur_cell = *m_iterator.cells) != 0; ++m_iterator.cells) { if(cur_cell->packed_coord != coord) break; area += cur_cell->area; m_iterator.cover += cur_cell->cover; } int alpha; if(cur_cell == 0 || cur_cell->y != m_iterator.last_y) { if(area) { alpha = calculate_alpha((m_iterator.cover << (poly_base_shift + 1)) - area); if(alpha) { sl.add_cell(last_x, alpha); } ++last_x; } break; } ++m_iterator.cells; if(area) { alpha = calculate_alpha((m_iterator.cover << (poly_base_shift + 1)) - area); if(alpha) { sl.add_cell(last_x, alpha); } ++last_x; } if(cur_cell->x > last_x) { alpha = calculate_alpha(m_iterator.cover << (poly_base_shift + 1)); if(alpha) { sl.add_span(last_x, cur_cell->x - last_x, alpha); } } } if(sl.num_spans()) { sl.finalize(m_iterator.last_y); break; } } return true; } //-------------------------------------------------------------------- bool hit_test(int tx, int ty); //-------------------------------------------------------------------- void add_xy(const double* x, const double* y, unsigned n) { if(n > 2) { move_to_d(*x++, *y++); --n; do { line_to_d(*x++, *y++); } while(--n); } } //------------------------------------------------------------------- template void add_path(VertexSource& vs, unsigned id=0) { double x; double y; unsigned cmd; vs.rewind(id); while(!is_stop(cmd = vs.vertex(&x, &y))) { add_vertex(x, y, cmd); } } private: //-------------------------------------------------------------------- // Disable copying rasterizer_scanline_aa(const rasterizer_scanline_aa&); const rasterizer_scanline_aa& operator = (const rasterizer_scanline_aa&); //-------------------------------------------------------------------- void move_to_no_clip(int x, int y); void line_to_no_clip(int x, int y); void close_polygon_no_clip(); void clip_segment(int x, int y); private: outline_aa m_outline; int m_gamma[aa_num]; filling_rule_e m_filling_rule; int m_clipped_start_x; int m_clipped_start_y; int m_start_x; int m_start_y; int m_prev_x; int m_prev_y; unsigned m_prev_flags; unsigned m_status; rect m_clip_box; bool m_clipping; iterator m_iterator; }; //------------------------------------------------------------------------ template void rasterizer_scanline_aa::reset() { m_outline.reset(); m_status = status_initial; } //------------------------------------------------------------------------ template void rasterizer_scanline_aa::filling_rule(filling_rule_e filling_rule) { m_filling_rule = filling_rule; } //------------------------------------------------------------------------ template void rasterizer_scanline_aa::clip_box(double x1, double y1, double x2, double y2) { reset(); m_clip_box = rect(poly_coord(x1), poly_coord(y1), poly_coord(x2), poly_coord(y2)); m_clip_box.normalize(); m_clipping = true; } //------------------------------------------------------------------------ template void rasterizer_scanline_aa::reset_clipping() { reset(); m_clipping = false; } //------------------------------------------------------------------------ template void rasterizer_scanline_aa::move_to_no_clip(int x, int y) { if(m_status == status_line_to) { close_polygon_no_clip(); } m_outline.move_to(x, y); m_clipped_start_x = x; m_clipped_start_y = y; m_status = status_line_to; } //------------------------------------------------------------------------ template void rasterizer_scanline_aa::line_to_no_clip(int x, int y) { if(m_status != status_initial) { m_outline.line_to(x, y); m_status = status_line_to; } } //------------------------------------------------------------------------ template void rasterizer_scanline_aa::close_polygon_no_clip() { if(m_status == status_line_to) { m_outline.line_to(m_clipped_start_x, m_clipped_start_y); m_status = status_closed; } } //------------------------------------------------------------------------ template void rasterizer_scanline_aa::clip_segment(int x, int y) { unsigned flags = clipping_flags(x, y, m_clip_box); if(m_prev_flags == flags) { if(flags == 0) { if(m_status == status_initial) { move_to_no_clip(x, y); } else { line_to_no_clip(x, y); } } } else { int cx[4]; int cy[4]; unsigned n = clip_liang_barsky(m_prev_x, m_prev_y, x, y, m_clip_box, cx, cy); const int* px = cx; const int* py = cy; while(n--) { if(m_status == status_initial) { move_to_no_clip(*px++, *py++); } else { line_to_no_clip(*px++, *py++); } } } m_prev_flags = flags; m_prev_x = x; m_prev_y = y; } //------------------------------------------------------------------------ template void rasterizer_scanline_aa::add_vertex(double x, double y, unsigned cmd) { if(is_close(cmd)) { close_polygon(); } else { if(is_move_to(cmd)) { move_to(poly_coord(x), poly_coord(y)); } else { if(is_vertex(cmd)) { line_to(poly_coord(x), poly_coord(y)); } } } } //------------------------------------------------------------------------ template void rasterizer_scanline_aa::move_to(int x, int y) { if(m_clipping) { if(m_outline.sorted()) { reset(); } if(m_status == status_line_to) { close_polygon(); } m_prev_x = m_start_x = x; m_prev_y = m_start_y = y; m_status = status_initial; m_prev_flags = clipping_flags(x, y, m_clip_box); if(m_prev_flags == 0) { move_to_no_clip(x, y); } } else { move_to_no_clip(x, y); } } //------------------------------------------------------------------------ template void rasterizer_scanline_aa::line_to(int x, int y) { if(m_clipping) { clip_segment(x, y); } else { line_to_no_clip(x, y); } } //------------------------------------------------------------------------ template void rasterizer_scanline_aa::close_polygon() { if(m_clipping) { clip_segment(m_start_x, m_start_y); } close_polygon_no_clip(); } //------------------------------------------------------------------------ template void rasterizer_scanline_aa::move_to_d(double x, double y) { move_to(poly_coord(x), poly_coord(y)); } //------------------------------------------------------------------------ template void rasterizer_scanline_aa::line_to_d(double x, double y) { line_to(poly_coord(x), poly_coord(y)); } //------------------------------------------------------------------------ template bool rasterizer_scanline_aa::hit_test(int tx, int ty) { close_polygon(); const cell_aa* const* cells = m_outline.cells(); if(m_outline.num_cells() == 0) return false; int cover = 0; const cell_aa* cur_cell = *cells++; for(;;) { int alpha; int coord = cur_cell->packed_coord; int x = cur_cell->x; int y = cur_cell->y; if(y > ty) return false; int area = cur_cell->area; cover += cur_cell->cover; while((cur_cell = *cells++) != 0) { if(cur_cell->packed_coord != coord) break; area += cur_cell->area; cover += cur_cell->cover; } if(area) { alpha = calculate_alpha((cover << (poly_base_shift + 1)) - area); if(alpha) { if(tx == x && ty == y) return true; } x++; } if(!cur_cell) break; if(cur_cell->x > x) { alpha = calculate_alpha(cover << (poly_base_shift + 1)); if(alpha) { if(ty == y && tx >= x && tx <= cur_cell->x) return true; } } } return false; } } #endif aggdraw-1.3.14/agg2/include/agg_render_scanlines.h000066400000000000000000000040551417726601400220000ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_RENDER_SCANLINES_INCLUDED #define AGG_RENDER_SCANLINES_INCLUDED #include "agg_basics.h" namespace agg { //========================================================render_scanlines template void render_scanlines(Rasterizer& ras, Scanline& sl, Renderer& ren) { if(ras.rewind_scanlines()) { sl.reset(ras.min_x(), ras.max_x()); ren.prepare(unsigned(ras.max_x() - ras.min_x() + 2)); while(ras.sweep_scanline(sl)) { ren.render(sl); } } } //========================================================render_all_paths template void render_all_paths(Rasterizer& ras, Scanline& sl, Renderer& r, VertexSource& vs, const ColorStorage& as, const PathId& id, unsigned num_paths) { for(unsigned i = 0; i < num_paths; i++) { ras.reset(); ras.add_path(vs, id[i]); r.color(as[i]); render_scanlines(ras, sl, r); } } } #endif aggdraw-1.3.14/agg2/include/agg_renderer_base.h000066400000000000000000000340731417726601400212650ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // class renderer_base // //---------------------------------------------------------------------------- #ifndef AGG_RENDERER_BASE_INCLUDED #define AGG_RENDERER_BASE_INCLUDED #include "agg_basics.h" #include "agg_rendering_buffer.h" namespace agg { //-----------------------------------------------------------renderer_base template class renderer_base { public: typedef PixelFormat pixfmt_type; typedef typename pixfmt_type::color_type color_type; //-------------------------------------------------------------------- renderer_base(pixfmt_type& ren) : m_ren(&ren), m_clip_box(0, 0, ren.width() - 1, ren.height() - 1) { } //-------------------------------------------------------------------- const pixfmt_type& ren() const { return *m_ren; } pixfmt_type& ren() { return *m_ren; } //-------------------------------------------------------------------- unsigned width() const { return m_ren->width(); } unsigned height() const { return m_ren->height(); } //-------------------------------------------------------------------- bool clip_box(int x1, int y1, int x2, int y2) { rect cb(x1, y1, x2, y2); cb.normalize(); if(cb.clip(rect(0, 0, width() - 1, height() - 1))) { m_clip_box = cb; return true; } m_clip_box.x1 = 1; m_clip_box.y1 = 1; m_clip_box.x2 = 0; m_clip_box.y2 = 0; return false; } //-------------------------------------------------------------------- void reset_clipping(bool visibility) { if(visibility) { m_clip_box.x1 = 0; m_clip_box.y1 = 0; m_clip_box.x2 = width() - 1; m_clip_box.y2 = height() - 1; } else { m_clip_box.x1 = 1; m_clip_box.y1 = 1; m_clip_box.x2 = 0; m_clip_box.y2 = 0; } } //-------------------------------------------------------------------- void clip_box_naked(int x1, int y1, int x2, int y2) { m_clip_box.x1 = x1; m_clip_box.y1 = y1; m_clip_box.x2 = x2; m_clip_box.y2 = y2; } //-------------------------------------------------------------------- bool inbox(int x, int y) const { return x >= m_clip_box.x1 && y >= m_clip_box.y1 && x <= m_clip_box.x2 && y <= m_clip_box.y2; } //-------------------------------------------------------------------- void first_clip_box() {} bool next_clip_box() { return false; } //-------------------------------------------------------------------- const rect& clip_box() const { return m_clip_box; } int xmin() const { return m_clip_box.x1; } int ymin() const { return m_clip_box.y1; } int xmax() const { return m_clip_box.x2; } int ymax() const { return m_clip_box.y2; } //-------------------------------------------------------------------- const rect& bounding_clip_box() const { return m_clip_box; } int bounding_xmin() const { return m_clip_box.x1; } int bounding_ymin() const { return m_clip_box.y1; } int bounding_xmax() const { return m_clip_box.x2; } int bounding_ymax() const { return m_clip_box.y2; } //-------------------------------------------------------------------- void clear(const color_type& c) { unsigned y; if(width()) { for(y = 0; y < height(); y++) { m_ren->copy_hline(0, y, width(), c); } } } //-------------------------------------------------------------------- void copy_pixel(int x, int y, const color_type& c) { if(inbox(x, y)) { m_ren->copy_pixel(x, y, c); } } //-------------------------------------------------------------------- void blend_pixel(int x, int y, const color_type& c, cover_type cover) { if(inbox(x, y)) { m_ren->blend_pixel(x, y, c, cover); } } //-------------------------------------------------------------------- color_type pixel(int x, int y) const { return inbox(x, y) ? m_ren->pixel(x, y) : color_type::no_color(); } //-------------------------------------------------------------------- void copy_hline(int x1, int y, int x2, const color_type& c) { if(x1 > x2) { int t = x2; x2 = x1; x1 = t; } if(y > ymax()) return; if(y < ymin()) return; if(x1 > xmax()) return; if(x2 < xmin()) return; if(x1 < xmin()) x1 = xmin(); if(x2 > xmax()) x2 = xmax(); m_ren->copy_hline(x1, y, x2 - x1 + 1, c); } //-------------------------------------------------------------------- void copy_vline(int x, int y1, int y2, const color_type& c) { if(y1 > y2) { int t = y2; y2 = y1; y1 = t; } if(x > xmax()) return; if(x < xmin()) return; if(y1 > ymax()) return; if(y2 < ymin()) return; if(y1 < ymin()) y1 = ymin(); if(y2 > ymax()) y2 = ymax(); m_ren->copy_vline(x, y1, y2 - y1 + 1, c); } //-------------------------------------------------------------------- void blend_hline(int x1, int y, int x2, const color_type& c, cover_type cover) { if(x1 > x2) { int t = x2; x2 = x1; x1 = t; } if(y > ymax()) return; if(y < ymin()) return; if(x1 > xmax()) return; if(x2 < xmin()) return; if(x1 < xmin()) x1 = xmin(); if(x2 > xmax()) x2 = xmax(); m_ren->blend_hline(x1, y, x2 - x1 + 1, c, cover); } //-------------------------------------------------------------------- void blend_vline(int x, int y1, int y2, const color_type& c, cover_type cover) { if(y1 > y2) { int t = y2; y2 = y1; y1 = t; } if(x > xmax()) return; if(x < xmin()) return; if(y1 > ymax()) return; if(y2 < ymin()) return; if(y1 < ymin()) y1 = ymin(); if(y2 > ymax()) y2 = ymax(); m_ren->blend_vline(x, y1, y2 - y1 + 1, c, cover); } //-------------------------------------------------------------------- void copy_bar(int x1, int y1, int x2, int y2, const color_type& c) { rect rc(x1, y1, x2, y2); rc.normalize(); if(rc.clip(clip_box())) { int y; for(y = rc.y1; y <= rc.y2; y++) { m_ren->copy_hline(rc.x1, y, unsigned(rc.x2 - rc.x1 + 1), c); } } } //-------------------------------------------------------------------- void blend_bar(int x1, int y1, int x2, int y2, const color_type& c, cover_type cover) { rect rc(x1, y1, x2, y2); rc.normalize(); if(rc.clip(clip_box())) { int y; for(y = rc.y1; y <= rc.y2; y++) { m_ren->blend_hline(rc.x1, y, unsigned(rc.x2 - rc.x1 + 1), c, cover); } } } //-------------------------------------------------------------------- void blend_solid_hspan(int x, int y, int len, const color_type& c, const cover_type* covers) { if(y > ymax()) return; if(y < ymin()) return; if(x < xmin()) { len -= xmin() - x; if(len <= 0) return; covers += xmin() - x; x = xmin(); } if(x + len > xmax()) { len = xmax() - x + 1; if(len <= 0) return; } m_ren->blend_solid_hspan(x, y, len, c, covers); } //-------------------------------------------------------------------- void blend_solid_vspan(int x, int y, int len, const color_type& c, const cover_type* covers) { if(x > xmax()) return; if(x < xmin()) return; if(y < ymin()) { len -= ymin() - y; if(len <= 0) return; covers += ymin() - y; y = ymin(); } if(y + len > ymax()) { len = ymax() - y + 1; if(len <= 0) return; } m_ren->blend_solid_vspan(x, y, len, c, covers); } //-------------------------------------------------------------------- void blend_color_hspan(int x, int y, int len, const color_type* colors, const cover_type* covers, cover_type cover = cover_full) { if(y > ymax()) return; if(y < ymin()) return; if(x < xmin()) { int d = xmin() - x; len -= d; if(len <= 0) return; if(covers) covers += d; colors += d; x = xmin(); } if(x + len > xmax()) { len = xmax() - x + 1; if(len <= 0) return; } m_ren->blend_color_hspan(x, y, len, colors, covers, cover); } //-------------------------------------------------------------------- void blend_color_vspan(int x, int y, int len, const color_type* colors, const cover_type* covers, cover_type cover = cover_full) { if(x > xmax()) return; if(x < xmin()) return; if(y < ymin()) { int d = ymin() - y; len -= d; if(len <= 0) return; if(covers) covers += d; colors += d; y = ymin(); } if(y + len > ymax()) { len = ymax() - y + 1; if(len <= 0) return; } m_ren->blend_color_vspan(x, y, len, colors, covers, cover); } //-------------------------------------------------------------------- void blend_color_hspan_no_clip(int x, int y, int len, const color_type* colors, const cover_type* covers, cover_type cover = cover_full) { m_ren->blend_color_hspan(x, y, len, colors, covers, cover); } //-------------------------------------------------------------------- void blend_color_vspan_no_clip(int x, int y, int len, const color_type* colors, const cover_type* covers, cover_type cover = cover_full) { m_ren->blend_color_vspan(x, y, len, colors, covers, cover); } //-------------------------------------------------------------------- void copy_from(const rendering_buffer& from, const rect* rc=0, int x_to=0, int y_to=0) { rect tmp_rect(0, 0, from.width(), from.height()); if(rc == 0) { rc = &tmp_rect; } rect rc2(*rc); rc2.normalize(); if(rc2.clip(rect(0, 0, from.width() - 1, from.height() - 1))) { rect rc3(x_to + rc2.x1 - rc->x1, y_to + rc2.y1 - rc->y1, x_to + rc2.x2 - rc->x1, y_to + rc2.y2 - rc->y1); rc3.normalize(); if(rc3.clip(clip_box())) { while(rc3.y1 <= rc3.y2) { m_ren->copy_from(from, rc3.x1, rc3.y1, rc2.x1, rc2.y1, rc3.x2 - rc3.x1 + 1); ++rc2.y1; ++rc3.y1; } } } } private: pixfmt_type* m_ren; rect m_clip_box; }; } #endif aggdraw-1.3.14/agg2/include/agg_renderer_markers.h000066400000000000000000001062761417726601400220240ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // class renderer_markers // //---------------------------------------------------------------------------- #ifndef AGG_RENDERER_MARKERS_INCLUDED #define AGG_RENDERER_MARKERS_INCLUDED #include "agg_basics.h" #include "agg_renderer_primitives.h" namespace agg { //---------------------------------------------------------------marker_e enum marker_e { marker_square, marker_diamond, marker_circle, marker_crossed_circle, marker_semiellipse_left, marker_semiellipse_right, marker_semiellipse_up, marker_semiellipse_down, marker_triangle_left, marker_triangle_right, marker_triangle_up, marker_triangle_down, marker_four_rays, marker_cross, marker_x, marker_dash, marker_dot, marker_pixel, end_of_markers }; //--------------------------------------------------------renderer_markers template class renderer_markers : public renderer_primitives { public: typedef renderer_primitives base_type; typedef BaseRenderer base_ren_type; typedef typename base_ren_type::color_type color_type; //-------------------------------------------------------------------- renderer_markers(base_ren_type& rbuf) : base_type(rbuf) { } //-------------------------------------------------------------------- bool visible(int x, int y, int r) const { rect rc(x-r, y-r, x+y, y+r); return rc.clip(base_type::ren().bounding_clip_box()); } //-------------------------------------------------------------------- void square(int x, int y, int r) { if(visible(x, y, r)) { if(r) base_type::outlined_rectangle(x-r, y-r, x+r, y+r); else base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); } } //-------------------------------------------------------------------- void diamond(int x, int y, int r) { if(visible(x, y, r)) { if(r) { int dy = -r; int dx = 0; do { base_type::ren().blend_pixel(x - dx, y + dy, base_type::line_color(), cover_full); base_type::ren().blend_pixel(x + dx, y + dy, base_type::line_color(), cover_full); base_type::ren().blend_pixel(x - dx, y - dy, base_type::line_color(), cover_full); base_type::ren().blend_pixel(x + dx, y - dy, base_type::line_color(), cover_full); if(dx) { base_type::ren().blend_hline(x-dx+1, y+dy, x+dx-1, base_type::fill_color(), cover_full); base_type::ren().blend_hline(x-dx+1, y-dy, x+dx-1, base_type::fill_color(), cover_full); } ++dy; ++dx; } while(dy <= 0); } else { base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); } } } //-------------------------------------------------------------------- void circle(int x, int y, int r) { if(visible(x, y, r)) { if(r) base_type::outlined_ellipse(x, y, r, r); else base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); } } //-------------------------------------------------------------------- void crossed_circle(int x, int y, int r) { if(visible(x, y, r)) { if(r) { base_type::outlined_ellipse(x, y, r, r); int r6 = r + (r >> 1); if(r <= 2) r6++; r >>= 1; base_type::ren().blend_hline(x-r6, y, x-r, base_type::line_color(), cover_full); base_type::ren().blend_hline(x+r, y, x+r6, base_type::line_color(), cover_full); base_type::ren().blend_vline(x, y-r6, y-r, base_type::line_color(), cover_full); base_type::ren().blend_vline(x, y+r, y+r6, base_type::line_color(), cover_full); } else { base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); } } } //------------------------------------------------------------------------ void semiellipse_left(int x, int y, int r) { if(visible(x, y, r)) { if(r) { int r8 = r * 4 / 5; int dy = -r; int dx = 0; ellipse_bresenham_interpolator ei(r * 3 / 5, r+r8); do { dx += ei.dx(); dy += ei.dy(); base_type::ren().blend_pixel(x + dy, y + dx, base_type::line_color(), cover_full); base_type::ren().blend_pixel(x + dy, y - dx, base_type::line_color(), cover_full); if(ei.dy() && dx) { base_type::ren().blend_vline(x+dy, y-dx+1, y+dx-1, base_type::fill_color(), cover_full); } ++ei; } while(dy < r8); base_type::ren().blend_vline(x+dy, y-dx, y+dx, base_type::line_color(), cover_full); } else { base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); } } } //-------------------------------------------------------------------- void semiellipse_right(int x, int y, int r) { if(visible(x, y, r)) { if(r) { int r8 = r * 4 / 5; int dy = -r; int dx = 0; ellipse_bresenham_interpolator ei(r * 3 / 5, r+r8); do { dx += ei.dx(); dy += ei.dy(); base_type::ren().blend_pixel(x - dy, y + dx, base_type::line_color(), cover_full); base_type::ren().blend_pixel(x - dy, y - dx, base_type::line_color(), cover_full); if(ei.dy() && dx) { base_type::ren().blend_vline(x-dy, y-dx+1, y+dx-1, base_type::fill_color(), cover_full); } ++ei; } while(dy < r8); base_type::ren().blend_vline(x-dy, y-dx, y+dx, base_type::line_color(), cover_full); } else { base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); } } } //-------------------------------------------------------------------- void semiellipse_up(int x, int y, int r) { if(visible(x, y, r)) { if(r) { int r8 = r * 4 / 5; int dy = -r; int dx = 0; ellipse_bresenham_interpolator ei(r * 3 / 5, r+r8); do { dx += ei.dx(); dy += ei.dy(); base_type::ren().blend_pixel(x + dx, y - dy, base_type::line_color(), cover_full); base_type::ren().blend_pixel(x - dx, y - dy, base_type::line_color(), cover_full); if(ei.dy() && dx) { base_type::ren().blend_hline(x-dx+1, y-dy, x+dx-1, base_type::fill_color(), cover_full); } ++ei; } while(dy < r8); base_type::ren().blend_hline(x-dx, y-dy-1, x+dx, base_type::line_color(), cover_full); } else { base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); } } } //-------------------------------------------------------------------- void semiellipse_down(int x, int y, int r) { if(visible(x, y, r)) { if(r) { int r8 = r * 4 / 5; int dy = -r; int dx = 0; ellipse_bresenham_interpolator ei(r * 3 / 5, r+r8); do { dx += ei.dx(); dy += ei.dy(); base_type::ren().blend_pixel(x + dx, y + dy, base_type::line_color(), cover_full); base_type::ren().blend_pixel(x - dx, y + dy, base_type::line_color(), cover_full); if(ei.dy() && dx) { base_type::ren().blend_hline(x-dx+1, y+dy, x+dx-1, base_type::fill_color(), cover_full); } ++ei; } while(dy < r8); base_type::ren().blend_hline(x-dx, y+dy+1, x+dx, base_type::line_color(), cover_full); } else { base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); } } } //-------------------------------------------------------------------- void triangle_left(int x, int y, int r) { if(visible(x, y, r)) { if(r) { int dy = -r; int dx = 0; int flip = 0; int r6 = r * 3 / 5; do { base_type::ren().blend_pixel(x + dy, y - dx, base_type::line_color(), cover_full); base_type::ren().blend_pixel(x + dy, y + dx, base_type::line_color(), cover_full); if(dx) { base_type::ren().blend_vline(x+dy, y-dx+1, y+dx-1, base_type::fill_color(), cover_full); } ++dy; dx += flip; flip ^= 1; } while(dy < r6); base_type::ren().blend_vline(x+dy, y-dx, y+dx, base_type::line_color(), cover_full); } else { base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); } } } //-------------------------------------------------------------------- void triangle_right(int x, int y, int r) { if(visible(x, y, r)) { if(r) { int dy = -r; int dx = 0; int flip = 0; int r6 = r * 3 / 5; do { base_type::ren().blend_pixel(x - dy, y - dx, base_type::line_color(), cover_full); base_type::ren().blend_pixel(x - dy, y + dx, base_type::line_color(), cover_full); if(dx) { base_type::ren().blend_vline(x-dy, y-dx+1, y+dx-1, base_type::fill_color(), cover_full); } ++dy; dx += flip; flip ^= 1; } while(dy < r6); base_type::ren().blend_vline(x-dy, y-dx, y+dx, base_type::line_color(), cover_full); } else { base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); } } } //-------------------------------------------------------------------- void triangle_up(int x, int y, int r) { if(visible(x, y, r)) { if(r) { int dy = -r; int dx = 0; int flip = 0; int r6 = r * 3 / 5; do { base_type::ren().blend_pixel(x - dx, y - dy, base_type::line_color(), cover_full); base_type::ren().blend_pixel(x + dx, y - dy, base_type::line_color(), cover_full); if(dx) { base_type::ren().blend_hline(x-dx+1, y-dy, x+dx-1, base_type::fill_color(), cover_full); } ++dy; dx += flip; flip ^= 1; } while(dy < r6); base_type::ren().blend_hline(x-dx, y-dy, x+dx, base_type::line_color(), cover_full); } else { base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); } } } //-------------------------------------------------------------------- void triangle_down(int x, int y, int r) { if(visible(x, y, r)) { if(r) { int dy = -r; int dx = 0; int flip = 0; int r6 = r * 3 / 5; do { base_type::ren().blend_pixel(x - dx, y + dy, base_type::line_color(), cover_full); base_type::ren().blend_pixel(x + dx, y + dy, base_type::line_color(), cover_full); if(dx) { base_type::ren().blend_hline(x-dx+1, y+dy, x+dx-1, base_type::fill_color(), cover_full); } ++dy; dx += flip; flip ^= 1; } while(dy < r6); base_type::ren().blend_hline(x-dx, y+dy, x+dx, base_type::line_color(), cover_full); } else { base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); } } } //-------------------------------------------------------------------- void four_rays(int x, int y, int r) { if(visible(x, y, r)) { if(r) { int dy = -r; int dx = 0; int flip = 0; int r3 = -(r / 3); do { base_type::ren().blend_pixel(x - dx, y + dy, base_type::line_color(), cover_full); base_type::ren().blend_pixel(x + dx, y + dy, base_type::line_color(), cover_full); base_type::ren().blend_pixel(x - dx, y - dy, base_type::line_color(), cover_full); base_type::ren().blend_pixel(x + dx, y - dy, base_type::line_color(), cover_full); base_type::ren().blend_pixel(x + dy, y - dx, base_type::line_color(), cover_full); base_type::ren().blend_pixel(x + dy, y + dx, base_type::line_color(), cover_full); base_type::ren().blend_pixel(x - dy, y - dx, base_type::line_color(), cover_full); base_type::ren().blend_pixel(x - dy, y + dx, base_type::line_color(), cover_full); if(dx) { base_type::ren().blend_hline(x-dx+1, y+dy, x+dx-1, base_type::fill_color(), cover_full); base_type::ren().blend_hline(x-dx+1, y-dy, x+dx-1, base_type::fill_color(), cover_full); base_type::ren().blend_vline(x+dy, y-dx+1, y+dx-1, base_type::fill_color(), cover_full); base_type::ren().blend_vline(x-dy, y-dx+1, y+dx-1, base_type::fill_color(), cover_full); } ++dy; dx += flip; flip ^= 1; } while(dy <= r3); base_type::solid_rectangle(x+r3+1, y+r3+1, x-r3-1, y-r3-1); } else { base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); } } } //-------------------------------------------------------------------- void cross(int x, int y, int r) { if(visible(x, y, r)) { if(r) { base_type::ren().blend_vline(x, y-r, y+r, base_type::line_color(), cover_full); base_type::ren().blend_hline(x-r, y, x+r, base_type::line_color(), cover_full); } else { base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); } } } //-------------------------------------------------------------------- void xing(int x, int y, int r) { if(visible(x, y, r)) { if(r) { int dy = -r * 7 / 10; do { base_type::ren().blend_pixel(x + dy, y + dy, base_type::line_color(), cover_full); base_type::ren().blend_pixel(x - dy, y + dy, base_type::line_color(), cover_full); base_type::ren().blend_pixel(x + dy, y - dy, base_type::line_color(), cover_full); base_type::ren().blend_pixel(x - dy, y - dy, base_type::line_color(), cover_full); ++dy; } while(dy < 0); } base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); } } //-------------------------------------------------------------------- void dash(int x, int y, int r) { if(visible(x, y, r)) { if(r) base_type::ren().blend_hline(x-r, y, x+r, base_type::line_color(), cover_full); else base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); } } //-------------------------------------------------------------------- void dot(int x, int y, int r) { if(visible(x, y, r)) { if(r) base_type::solid_ellipse(x, y, r, r); else base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); } } //-------------------------------------------------------------------- void pixel(int x, int y, int) { base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); } //-------------------------------------------------------------------- void marker(int x, int y, int r, marker_e type) { switch(type) { case marker_square: square(x, y, r); break; case marker_diamond: diamond(x, y, r); break; case marker_circle: circle(x, y, r); break; case marker_crossed_circle: crossed_circle(x, y, r); break; case marker_semiellipse_left: semiellipse_left(x, y, r); break; case marker_semiellipse_right: semiellipse_right(x, y, r); break; case marker_semiellipse_up: semiellipse_up(x, y, r); break; case marker_semiellipse_down: semiellipse_down(x, y, r); break; case marker_triangle_left: triangle_left(x, y, r); break; case marker_triangle_right: triangle_right(x, y, r); break; case marker_triangle_up: triangle_up(x, y, r); break; case marker_triangle_down: triangle_down(x, y, r); break; case marker_four_rays: four_rays(x, y, r); break; case marker_cross: cross(x, y, r); break; case marker_x: xing(x, y, r); break; case marker_dash: dash(x, y, r); break; case marker_dot: dot(x, y, r); break; case marker_pixel: pixel(x, y, r); break; } } //-------------------------------------------------------------------- template void markers(int n, const T* x, const T* y, T r, marker_e type) { if(n <= 0) return; if(r == 0) { do { base_type::ren().blend_pixel(int(*x), int(*y), base_type::fill_color(), cover_full); ++x; ++y; } while(--n); return; } switch(type) { case marker_square: do { square (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; case marker_diamond: do { diamond (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; case marker_circle: do { circle (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; case marker_crossed_circle: do { crossed_circle (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; case marker_semiellipse_left: do { semiellipse_left (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; case marker_semiellipse_right: do { semiellipse_right(int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; case marker_semiellipse_up: do { semiellipse_up (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; case marker_semiellipse_down: do { semiellipse_down (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; case marker_triangle_left: do { triangle_left (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; case marker_triangle_right: do { triangle_right (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; case marker_triangle_up: do { triangle_up (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; case marker_triangle_down: do { triangle_down (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; case marker_four_rays: do { four_rays (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; case marker_cross: do { cross (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; case marker_x: do { xing (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; case marker_dash: do { dash (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; case marker_dot: do { dot (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; case marker_pixel: do { pixel (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; } } //-------------------------------------------------------------------- template void markers(int n, const T* x, const T* y, const T* r, marker_e type) { if(n <= 0) return; switch(type) { case marker_square: do { square (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; case marker_diamond: do { diamond (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; case marker_circle: do { circle (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; case marker_crossed_circle: do { crossed_circle (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; case marker_semiellipse_left: do { semiellipse_left (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; case marker_semiellipse_right: do { semiellipse_right(int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; case marker_semiellipse_up: do { semiellipse_up (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; case marker_semiellipse_down: do { semiellipse_down (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; case marker_triangle_left: do { triangle_left (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; case marker_triangle_right: do { triangle_right (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; case marker_triangle_up: do { triangle_up (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; case marker_triangle_down: do { triangle_down (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; case marker_four_rays: do { four_rays (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; case marker_cross: do { cross (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; case marker_x: do { xing (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; case marker_dash: do { dash (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; case marker_dot: do { dot (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; case marker_pixel: do { pixel (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; } } //-------------------------------------------------------------------- template void markers(int n, const T* x, const T* y, const T* r, const color_type* fc, marker_e type) { if(n <= 0) return; switch(type) { case marker_square: do { base_type::fill_color(*fc); square (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; case marker_diamond: do { base_type::fill_color(*fc); diamond (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; case marker_circle: do { base_type::fill_color(*fc); circle (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; case marker_crossed_circle: do { base_type::fill_color(*fc); crossed_circle (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; case marker_semiellipse_left: do { base_type::fill_color(*fc); semiellipse_left (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; case marker_semiellipse_right: do { base_type::fill_color(*fc); semiellipse_right(int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; case marker_semiellipse_up: do { base_type::fill_color(*fc); semiellipse_up (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; case marker_semiellipse_down: do { base_type::fill_color(*fc); semiellipse_down (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; case marker_triangle_left: do { base_type::fill_color(*fc); triangle_left (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; case marker_triangle_right: do { base_type::fill_color(*fc); triangle_right (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; case marker_triangle_up: do { base_type::fill_color(*fc); triangle_up (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; case marker_triangle_down: do { base_type::fill_color(*fc); triangle_down (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; case marker_four_rays: do { base_type::fill_color(*fc); four_rays (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; case marker_cross: do { base_type::fill_color(*fc); cross (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; case marker_x: do { base_type::fill_color(*fc); xing (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; case marker_dash: do { base_type::fill_color(*fc); dash (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; case marker_dot: do { base_type::fill_color(*fc); dot (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; case marker_pixel: do { base_type::fill_color(*fc); pixel (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; } } //-------------------------------------------------------------------- template void markers(int n, const T* x, const T* y, const T* r, const color_type* fc, const color_type* lc, marker_e type) { if(n <= 0) return; switch(type) { case marker_square: do { base_type::fill_color(*fc); base_type::line_color(*lc); square (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; case marker_diamond: do { base_type::fill_color(*fc); base_type::line_color(*lc); diamond (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; case marker_circle: do { base_type::fill_color(*fc); base_type::line_color(*lc); circle (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; case marker_crossed_circle: do { base_type::fill_color(*fc); base_type::line_color(*lc); crossed_circle (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; case marker_semiellipse_left: do { base_type::fill_color(*fc); base_type::line_color(*lc); semiellipse_left (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; case marker_semiellipse_right: do { base_type::fill_color(*fc); base_type::line_color(*lc); semiellipse_right(int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; case marker_semiellipse_up: do { base_type::fill_color(*fc); base_type::line_color(*lc); semiellipse_up (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; case marker_semiellipse_down: do { base_type::fill_color(*fc); base_type::line_color(*lc); semiellipse_down (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; case marker_triangle_left: do { base_type::fill_color(*fc); base_type::line_color(*lc); triangle_left (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; case marker_triangle_right: do { base_type::fill_color(*fc); base_type::line_color(*lc); triangle_right (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; case marker_triangle_up: do { base_type::fill_color(*fc); base_type::line_color(*lc); triangle_up (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; case marker_triangle_down: do { base_type::fill_color(*fc); base_type::line_color(*lc); triangle_down (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; case marker_four_rays: do { base_type::fill_color(*fc); base_type::line_color(*lc); four_rays (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; case marker_cross: do { base_type::fill_color(*fc); base_type::line_color(*lc); cross (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; case marker_x: do { base_type::fill_color(*fc); base_type::line_color(*lc); xing (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; case marker_dash: do { base_type::fill_color(*fc); base_type::line_color(*lc); dash (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; case marker_dot: do { base_type::fill_color(*fc); base_type::line_color(*lc); dot (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; case marker_pixel: do { base_type::fill_color(*fc); base_type::line_color(*lc); pixel (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; } } }; } #endif aggdraw-1.3.14/agg2/include/agg_renderer_mclip.h000066400000000000000000000263761417726601400214660ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // class renderer_mclip // //---------------------------------------------------------------------------- #ifndef AGG_RENDERER_MCLIP_INCLUDED #define AGG_RENDERER_MCLIP_INCLUDED #include "agg_basics.h" #include "agg_array.h" #include "agg_renderer_base.h" namespace agg { //----------------------------------------------------------renderer_mclip template class renderer_mclip { public: typedef PixelFormat pixfmt_type; typedef typename pixfmt_type::color_type color_type; typedef renderer_base base_ren_type; //-------------------------------------------------------------------- renderer_mclip(pixfmt_type& ren) : m_ren(ren), m_curr_cb(0), m_bounds(m_ren.xmin(), m_ren.ymin(), m_ren.xmax(), m_ren.ymax()) { } //-------------------------------------------------------------------- const pixfmt_type& ren() const { return m_ren.ren(); } pixfmt_type& ren() { return m_ren.ren(); } //-------------------------------------------------------------------- unsigned width() const { return m_ren.width(); } unsigned height() const { return m_ren.height(); } //-------------------------------------------------------------------- const rect& clip_box() const { return m_ren.clip_box(); } int xmin() const { return m_ren.xmin(); } int ymin() const { return m_ren.ymin(); } int xmax() const { return m_ren.xmax(); } int ymax() const { return m_ren.ymax(); } //-------------------------------------------------------------------- const rect& bounding_clip_box() const { return m_bounds; } int bounding_xmin() const { return m_bounds.x1; } int bounding_ymin() const { return m_bounds.y1; } int bounding_xmax() const { return m_bounds.x2; } int bounding_ymax() const { return m_bounds.y2; } //-------------------------------------------------------------------- void first_clip_box() { m_curr_cb = 0; if(m_clip.size()) { const rect& cb = m_clip[0]; m_ren.clip_box_naked(cb.x1, cb.y1, cb.x2, cb.y2); } } //-------------------------------------------------------------------- bool next_clip_box() { if(++m_curr_cb < m_clip.size()) { const rect& cb = m_clip[m_curr_cb]; m_ren.clip_box_naked(cb.x1, cb.y1, cb.x2, cb.y2); return true; } return false; } //-------------------------------------------------------------------- void reset_clipping(bool visibility) { m_ren.reset_clipping(visibility); m_clip.remove_all(); m_curr_cb = 0; m_bounds = m_ren.clip_box(); } //-------------------------------------------------------------------- void add_clip_box(int x1, int y1, int x2, int y2) { rect cb(x1, y1, x2, y2); cb.normalize(); if(cb.clip(rect(0, 0, width() - 1, height() - 1))) { m_clip.add(cb); if(cb.x1 < m_bounds.x1) m_bounds.x1 = cb.x1; if(cb.y1 < m_bounds.y1) m_bounds.y1 = cb.y1; if(cb.x2 > m_bounds.x2) m_bounds.x2 = cb.x2; if(cb.y2 > m_bounds.y2) m_bounds.y2 = cb.y2; } } //-------------------------------------------------------------------- void clear(const color_type& c) { m_ren.clear(c); } //-------------------------------------------------------------------- void copy_pixel(int x, int y, const color_type& c) { first_clip_box(); do { if(m_ren.inbox(x, y)) { m_ren.ren().copy_pixel(x, y, c); break; } } while(next_clip_box()); } //-------------------------------------------------------------------- void blend_pixel(int x, int y, const color_type& c, cover_type cover) { first_clip_box(); do { if(m_ren.inbox(x, y)) { m_ren.ren().blend_pixel(x, y, c, cover); break; } } while(next_clip_box()); } //-------------------------------------------------------------------- color_type pixel(int x, int y) const { first_clip_box(); do { if(m_ren.inbox(x, y)) { return m_ren.ren().pixel(x, y); } } while(next_clip_box()); return color_type::no_color(); } //-------------------------------------------------------------------- void copy_hline(int x1, int y, int x2, const color_type& c) { first_clip_box(); do { m_ren.copy_hline(x1, y, x2, c); } while(next_clip_box()); } //-------------------------------------------------------------------- void copy_vline(int x, int y1, int y2, const color_type& c) { first_clip_box(); do { m_ren.copy_vline(x, y1, y2, c); } while(next_clip_box()); } //-------------------------------------------------------------------- void blend_hline(int x1, int y, int x2, const color_type& c, cover_type cover) { first_clip_box(); do { m_ren.blend_hline(x1, y, x2, c, cover); } while(next_clip_box()); } //-------------------------------------------------------------------- void blend_vline(int x, int y1, int y2, const color_type& c, cover_type cover) { first_clip_box(); do { m_ren.blend_vline(x, y1, y2, c, cover); } while(next_clip_box()); } //-------------------------------------------------------------------- void copy_bar(int x1, int y1, int x2, int y2, const color_type& c) { first_clip_box(); do { m_ren.copy_bar(x1, y1, x2, y2, c); } while(next_clip_box()); } //-------------------------------------------------------------------- void blend_bar(int x1, int y1, int x2, int y2, const color_type& c, cover_type cover) { first_clip_box(); do { m_ren.blend_bar(x1, y1, x2, y2, c, cover); } while(next_clip_box()); } //-------------------------------------------------------------------- void blend_solid_hspan(int x, int y, int len, const color_type& c, const cover_type* covers) { first_clip_box(); do { m_ren.blend_solid_hspan(x, y, len, c, covers); } while(next_clip_box()); } //-------------------------------------------------------------------- void blend_solid_vspan(int x, int y, int len, const color_type& c, const cover_type* covers) { first_clip_box(); do { m_ren.blend_solid_vspan(x, y, len, c, covers); } while(next_clip_box()); } //-------------------------------------------------------------------- void blend_color_hspan(int x, int y, int len, const color_type* colors, const cover_type* covers, cover_type cover = cover_full) { first_clip_box(); do { m_ren.blend_color_hspan(x, y, len, colors, covers, cover); } while(next_clip_box()); } //-------------------------------------------------------------------- void blend_color_vspan(int x, int y, int len, const color_type* colors, const cover_type* covers, cover_type cover = cover_full) { first_clip_box(); do { m_ren.blend_color_hspan(x, y, len, colors, covers, cover); } while(next_clip_box()); } //-------------------------------------------------------------------- void blend_color_hspan_no_clip(int x, int y, int len, const color_type* colors, const cover_type* covers, cover_type cover = cover_full) { m_ren.blend_color_hspan_no_clip(x, y, len, colors, covers, cover); } //-------------------------------------------------------------------- void blend_color_vspan_no_clip(int x, int y, int len, const color_type* colors, const cover_type* covers, cover_type cover = cover_full) { m_ren.blend_color_vspan_no_clip(x, y, len, colors, covers, cover); } //-------------------------------------------------------------------- void copy_from(const rendering_buffer& from, const rect* rc=0, int x_to=0, int y_to=0) { first_clip_box(); do { m_ren.copy_from(from, rc, x_to, y_to); } while(next_clip_box()); } private: renderer_mclip(const renderer_mclip&); const renderer_mclip& operator = (const renderer_mclip&); base_ren_type m_ren; pod_deque m_clip; unsigned m_curr_cb; rect m_bounds; }; } #endif aggdraw-1.3.14/agg2/include/agg_renderer_outline_aa.h000066400000000000000000001462611417726601400224760ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_RENDERER_OUTLINE_AA_INCLUDED #define AGG_RENDERER_OUTLINE_AA_INCLUDED #include "agg_basics.h" #include "agg_math.h" #include "agg_line_aa_basics.h" #include "agg_dda_line.h" #include "agg_ellipse_bresenham.h" #include "agg_renderer_base.h" #include "agg_gamma_functions.h" namespace agg { //===================================================distance_interpolator0 class distance_interpolator0 { public: //--------------------------------------------------------------------- distance_interpolator0() {} distance_interpolator0(int x1, int y1, int x2, int y2, int x, int y) : m_dx(line_mr(x2) - line_mr(x1)), m_dy(line_mr(y2) - line_mr(y1)), m_dist((line_mr(x + line_subpixel_size/2) - line_mr(x2)) * m_dy - (line_mr(y + line_subpixel_size/2) - line_mr(y2)) * m_dx) { m_dx <<= line_mr_subpixel_shift; m_dy <<= line_mr_subpixel_shift; } //--------------------------------------------------------------------- void inc_x() { m_dist += m_dy; } void dec_x() { m_dist -= m_dy; } void inc_y() { m_dist -= m_dx; } void dec_y() { m_dist += m_dx; } //--------------------------------------------------------------------- void inc_x(int dy) { m_dist += m_dy; if(dy > 0) m_dist -= m_dx; if(dy < 0) m_dist += m_dx; } //--------------------------------------------------------------------- void dec_x(int dy) { m_dist -= m_dy; if(dy > 0) m_dist -= m_dx; if(dy < 0) m_dist += m_dx; } //--------------------------------------------------------------------- void inc_y(int dx) { m_dist -= m_dx; if(dx > 0) m_dist += m_dy; if(dx < 0) m_dist -= m_dy; } void dec_y(int dx) //--------------------------------------------------------------------- { m_dist += m_dx; if(dx > 0) m_dist += m_dy; if(dx < 0) m_dist -= m_dy; } //--------------------------------------------------------------------- int dist() const { return m_dist; } int dx() const { return m_dx; } int dy() const { return m_dy; } private: //--------------------------------------------------------------------- int m_dx; int m_dy; int m_dist; }; //===================================================distance_interpolator1 class distance_interpolator1 { public: //--------------------------------------------------------------------- distance_interpolator1() {} distance_interpolator1(int x1, int y1, int x2, int y2, int x, int y) : m_dx(x2 - x1), m_dy(y2 - y1), m_dist(int(double(x + line_subpixel_size/2 - x2) * double(m_dy) - double(y + line_subpixel_size/2 - y2) * double(m_dx))) { m_dx <<= line_subpixel_shift; m_dy <<= line_subpixel_shift; } //--------------------------------------------------------------------- void inc_x() { m_dist += m_dy; } void dec_x() { m_dist -= m_dy; } void inc_y() { m_dist -= m_dx; } void dec_y() { m_dist += m_dx; } //--------------------------------------------------------------------- void inc_x(int dy) { m_dist += m_dy; if(dy > 0) m_dist -= m_dx; if(dy < 0) m_dist += m_dx; } //--------------------------------------------------------------------- void dec_x(int dy) { m_dist -= m_dy; if(dy > 0) m_dist -= m_dx; if(dy < 0) m_dist += m_dx; } //--------------------------------------------------------------------- void inc_y(int dx) { m_dist -= m_dx; if(dx > 0) m_dist += m_dy; if(dx < 0) m_dist -= m_dy; } void dec_y(int dx) //--------------------------------------------------------------------- { m_dist += m_dx; if(dx > 0) m_dist += m_dy; if(dx < 0) m_dist -= m_dy; } //--------------------------------------------------------------------- int dist() const { return m_dist; } int dx() const { return m_dx; } int dy() const { return m_dy; } private: //--------------------------------------------------------------------- int m_dx; int m_dy; int m_dist; }; //===================================================distance_interpolator2 class distance_interpolator2 { public: //--------------------------------------------------------------------- distance_interpolator2() {} distance_interpolator2(int x1, int y1, int x2, int y2, int sx, int sy, int x, int y) : m_dx(x2 - x1), m_dy(y2 - y1), m_dx_start(line_mr(sx) - line_mr(x1)), m_dy_start(line_mr(sy) - line_mr(y1)), m_dist(int(double(x + line_subpixel_size/2 - x2) * double(m_dy) - double(y + line_subpixel_size/2 - y2) * double(m_dx))), m_dist_start((line_mr(x + line_subpixel_size/2) - line_mr(sx)) * m_dy_start - (line_mr(y + line_subpixel_size/2) - line_mr(sy)) * m_dx_start) { m_dx <<= line_subpixel_shift; m_dy <<= line_subpixel_shift; m_dx_start <<= line_mr_subpixel_shift; m_dy_start <<= line_mr_subpixel_shift; } distance_interpolator2(int x1, int y1, int x2, int y2, int ex, int ey, int x, int y, int) : m_dx(x2 - x1), m_dy(y2 - y1), m_dx_start(line_mr(ex) - line_mr(x2)), m_dy_start(line_mr(ey) - line_mr(y2)), m_dist(int(double(x + line_subpixel_size/2 - x2) * double(m_dy) - double(y + line_subpixel_size/2 - y2) * double(m_dx))), m_dist_start((line_mr(x + line_subpixel_size/2) - line_mr(ex)) * m_dy_start - (line_mr(y + line_subpixel_size/2) - line_mr(ey)) * m_dx_start) { m_dx <<= line_subpixel_shift; m_dy <<= line_subpixel_shift; m_dx_start <<= line_mr_subpixel_shift; m_dy_start <<= line_mr_subpixel_shift; } //--------------------------------------------------------------------- void inc_x() { m_dist += m_dy; m_dist_start += m_dy_start; } void dec_x() { m_dist -= m_dy; m_dist_start -= m_dy_start; } void inc_y() { m_dist -= m_dx; m_dist_start -= m_dx_start; } void dec_y() { m_dist += m_dx; m_dist_start += m_dx_start; } //--------------------------------------------------------------------- void inc_x(int dy) { m_dist += m_dy; m_dist_start += m_dy_start; if(dy > 0) { m_dist -= m_dx; m_dist_start -= m_dx_start; } if(dy < 0) { m_dist += m_dx; m_dist_start += m_dx_start; } } //--------------------------------------------------------------------- void dec_x(int dy) { m_dist -= m_dy; m_dist_start -= m_dy_start; if(dy > 0) { m_dist -= m_dx; m_dist_start -= m_dx_start; } if(dy < 0) { m_dist += m_dx; m_dist_start += m_dx_start; } } //--------------------------------------------------------------------- void inc_y(int dx) { m_dist -= m_dx; m_dist_start -= m_dx_start; if(dx > 0) { m_dist += m_dy; m_dist_start += m_dy_start; } if(dx < 0) { m_dist -= m_dy; m_dist_start -= m_dy_start; } } //--------------------------------------------------------------------- void dec_y(int dx) { m_dist += m_dx; m_dist_start += m_dx_start; if(dx > 0) { m_dist += m_dy; m_dist_start += m_dy_start; } if(dx < 0) { m_dist -= m_dy; m_dist_start -= m_dy_start; } } //--------------------------------------------------------------------- int dist() const { return m_dist; } int dist_start() const { return m_dist_start; } int dist_end() const { return m_dist_start; } //--------------------------------------------------------------------- int dx() const { return m_dx; } int dy() const { return m_dy; } int dx_start() const { return m_dx_start; } int dy_start() const { return m_dy_start; } int dx_end() const { return m_dx_start; } int dy_end() const { return m_dy_start; } private: //--------------------------------------------------------------------- int m_dx; int m_dy; int m_dx_start; int m_dy_start; int m_dist; int m_dist_start; }; //===================================================distance_interpolator3 class distance_interpolator3 { public: //--------------------------------------------------------------------- distance_interpolator3() {} distance_interpolator3(int x1, int y1, int x2, int y2, int sx, int sy, int ex, int ey, int x, int y) : m_dx(x2 - x1), m_dy(y2 - y1), m_dx_start(line_mr(sx) - line_mr(x1)), m_dy_start(line_mr(sy) - line_mr(y1)), m_dx_end(line_mr(ex) - line_mr(x2)), m_dy_end(line_mr(ey) - line_mr(y2)), m_dist(int(double(x + line_subpixel_size/2 - x2) * double(m_dy) - double(y + line_subpixel_size/2 - y2) * double(m_dx))), m_dist_start((line_mr(x + line_subpixel_size/2) - line_mr(sx)) * m_dy_start - (line_mr(y + line_subpixel_size/2) - line_mr(sy)) * m_dx_start), m_dist_end((line_mr(x + line_subpixel_size/2) - line_mr(ex)) * m_dy_end - (line_mr(y + line_subpixel_size/2) - line_mr(ey)) * m_dx_end) { m_dx <<= line_subpixel_shift; m_dy <<= line_subpixel_shift; m_dx_start <<= line_mr_subpixel_shift; m_dy_start <<= line_mr_subpixel_shift; m_dx_end <<= line_mr_subpixel_shift; m_dy_end <<= line_mr_subpixel_shift; } //--------------------------------------------------------------------- void inc_x() { m_dist += m_dy; m_dist_start += m_dy_start; m_dist_end += m_dy_end; } void dec_x() { m_dist -= m_dy; m_dist_start -= m_dy_start; m_dist_end -= m_dy_end; } void inc_y() { m_dist -= m_dx; m_dist_start -= m_dx_start; m_dist_end -= m_dx_end; } void dec_y() { m_dist += m_dx; m_dist_start += m_dx_start; m_dist_end += m_dx_end; } //--------------------------------------------------------------------- void inc_x(int dy) { m_dist += m_dy; m_dist_start += m_dy_start; m_dist_end += m_dy_end; if(dy > 0) { m_dist -= m_dx; m_dist_start -= m_dx_start; m_dist_end -= m_dx_end; } if(dy < 0) { m_dist += m_dx; m_dist_start += m_dx_start; m_dist_end += m_dx_end; } } //--------------------------------------------------------------------- void dec_x(int dy) { m_dist -= m_dy; m_dist_start -= m_dy_start; m_dist_end -= m_dy_end; if(dy > 0) { m_dist -= m_dx; m_dist_start -= m_dx_start; m_dist_end -= m_dx_end; } if(dy < 0) { m_dist += m_dx; m_dist_start += m_dx_start; m_dist_end += m_dx_end; } } //--------------------------------------------------------------------- void inc_y(int dx) { m_dist -= m_dx; m_dist_start -= m_dx_start; m_dist_end -= m_dx_end; if(dx > 0) { m_dist += m_dy; m_dist_start += m_dy_start; m_dist_end += m_dy_end; } if(dx < 0) { m_dist -= m_dy; m_dist_start -= m_dy_start; m_dist_end -= m_dy_end; } } //--------------------------------------------------------------------- void dec_y(int dx) { m_dist += m_dx; m_dist_start += m_dx_start; m_dist_end += m_dx_end; if(dx > 0) { m_dist += m_dy; m_dist_start += m_dy_start; m_dist_end += m_dy_end; } if(dx < 0) { m_dist -= m_dy; m_dist_start -= m_dy_start; m_dist_end -= m_dy_end; } } //--------------------------------------------------------------------- int dist() const { return m_dist; } int dist_start() const { return m_dist_start; } int dist_end() const { return m_dist_end; } //--------------------------------------------------------------------- int dx() const { return m_dx; } int dy() const { return m_dy; } int dx_start() const { return m_dx_start; } int dy_start() const { return m_dy_start; } int dx_end() const { return m_dx_end; } int dy_end() const { return m_dy_end; } private: //--------------------------------------------------------------------- int m_dx; int m_dy; int m_dx_start; int m_dy_start; int m_dx_end; int m_dy_end; int m_dist; int m_dist_start; int m_dist_end; }; //================================================line_interpolator_aa_base template class line_interpolator_aa_base { public: typedef Renderer renderer_type; typedef typename Renderer::color_type color_type; //--------------------------------------------------------------------- enum { max_half_width = 64 }; //--------------------------------------------------------------------- line_interpolator_aa_base(renderer_type& ren, const line_parameters& lp) : m_lp(&lp), m_li(lp.vertical ? line_dbl_hr(lp.x2 - lp.x1) : line_dbl_hr(lp.y2 - lp.y1), lp.vertical ? abs(lp.y2 - lp.y1) : abs(lp.x2 - lp.x1) + 1), m_ren(ren), m_len((lp.vertical == (lp.inc > 0)) ? -lp.len : lp.len), m_x(lp.x1 >> line_subpixel_shift), m_y(lp.y1 >> line_subpixel_shift), m_old_x(m_x), m_old_y(m_y), m_count((lp.vertical ? abs((lp.y2 >> line_subpixel_shift) - m_y) : abs((lp.x2 >> line_subpixel_shift) - m_x))), m_width(ren.subpixel_width()), m_max_extent(m_width >> (line_subpixel_shift - 2)), m_step(0) { agg::dda2_line_interpolator li(0, lp.vertical ? (lp.dy << agg::line_subpixel_shift) : (lp.dx << agg::line_subpixel_shift), lp.len); unsigned i; int stop = m_width + line_subpixel_size * 2; for(i = 0; i < max_half_width; ++i) { m_dist[i] = li.y(); if(m_dist[i] >= stop) break; ++li; } m_dist[i++] = 0x7FFF0000; } //--------------------------------------------------------------------- template int step_hor_base(DI& di) { ++m_li; m_x += m_lp->inc; m_y = (m_lp->y1 + m_li.y()) >> line_subpixel_shift; if(m_lp->inc > 0) di.inc_x(m_y - m_old_y); else di.dec_x(m_y - m_old_y); m_old_y = m_y; return di.dist() / m_len; } //--------------------------------------------------------------------- template int step_ver_base(DI& di) { ++m_li; m_y += m_lp->inc; m_x = (m_lp->x1 + m_li.y()) >> line_subpixel_shift; if(m_lp->inc > 0) di.inc_y(m_x - m_old_x); else di.dec_y(m_x - m_old_x); m_old_x = m_x; return di.dist() / m_len; } //--------------------------------------------------------------------- bool vertical() const { return m_lp->vertical; } int width() const { return m_width; } int count() const { return m_count; } private: line_interpolator_aa_base(const line_interpolator_aa_base&); const line_interpolator_aa_base& operator = (const line_interpolator_aa_base&); protected: const line_parameters* m_lp; dda2_line_interpolator m_li; renderer_type& m_ren; int m_len; int m_x; int m_y; int m_old_x; int m_old_y; int m_count; int m_width; int m_max_extent; int m_step; int m_dist[max_half_width + 1]; cover_type m_covers[max_half_width * 2 + 4]; }; //====================================================line_interpolator_aa0 template class line_interpolator_aa0 : public line_interpolator_aa_base { public: typedef Renderer renderer_type; typedef typename Renderer::color_type color_type; typedef line_interpolator_aa_base base_type; //--------------------------------------------------------------------- line_interpolator_aa0(renderer_type& ren, const line_parameters& lp) : line_interpolator_aa_base(ren, lp), m_di(lp.x1, lp.y1, lp.x2, lp.y2, lp.x1 & ~line_subpixel_mask, lp.y1 & ~line_subpixel_mask) { base_type::m_li.adjust_forward(); } //--------------------------------------------------------------------- bool step_hor() { int dist; int dy; int s1 = base_type::step_hor_base(m_di); cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2; cover_type* p1 = p0; *p1++ = (cover_type)base_type::m_ren.cover(s1); dy = 1; while((dist = base_type::m_dist[dy] - s1) <= base_type::m_width) { *p1++ = (cover_type)base_type::m_ren.cover(dist); ++dy; } dy = 1; while((dist = base_type::m_dist[dy] + s1) <= base_type::m_width) { *--p0 = (cover_type)base_type::m_ren.cover(dist); ++dy; } base_type::m_ren.blend_solid_vspan(base_type::m_x, base_type::m_y - dy + 1, unsigned(p1 - p0), p0); return ++base_type::m_step < base_type::m_count; } //--------------------------------------------------------------------- bool step_ver() { int dist; int dx; int s1 = base_type::step_ver_base(m_di); cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2; cover_type* p1 = p0; *p1++ = (cover_type)base_type::m_ren.cover(s1); dx = 1; while((dist = base_type::m_dist[dx] - s1) <= base_type::m_width) { *p1++ = (cover_type)base_type::m_ren.cover(dist); ++dx; } dx = 1; while((dist = base_type::m_dist[dx] + s1) <= base_type::m_width) { *--p0 = (cover_type)base_type::m_ren.cover(dist); ++dx; } base_type::m_ren.blend_solid_hspan(base_type::m_x - dx + 1, base_type::m_y, unsigned(p1 - p0), p0); return ++base_type::m_step < base_type::m_count; } private: line_interpolator_aa0(const line_interpolator_aa0&); const line_interpolator_aa0& operator = (const line_interpolator_aa0&); //--------------------------------------------------------------------- distance_interpolator1 m_di; }; //====================================================line_interpolator_aa1 template class line_interpolator_aa1 : public line_interpolator_aa_base { public: typedef Renderer renderer_type; typedef typename Renderer::color_type color_type; typedef line_interpolator_aa_base base_type; //--------------------------------------------------------------------- line_interpolator_aa1(renderer_type& ren, const line_parameters& lp, int sx, int sy) : line_interpolator_aa_base(ren, lp), m_di(lp.x1, lp.y1, lp.x2, lp.y2, sx, sy, lp.x1 & ~line_subpixel_mask, lp.y1 & ~line_subpixel_mask) { int dist1_start; int dist2_start; int npix = 1; if(lp.vertical) { do { --base_type::m_li; base_type::m_y -= lp.inc; base_type::m_x = (base_type::m_lp->x1 + base_type::m_li.y()) >> line_subpixel_shift; if(lp.inc > 0) m_di.dec_y(base_type::m_x - base_type::m_old_x); else m_di.inc_y(base_type::m_x - base_type::m_old_x); base_type::m_old_x = base_type::m_x; dist1_start = dist2_start = m_di.dist_start(); int dx = 0; if(dist1_start < 0) ++npix; do { dist1_start += m_di.dy_start(); dist2_start -= m_di.dy_start(); if(dist1_start < 0) ++npix; if(dist2_start < 0) ++npix; ++dx; } while(base_type::m_dist[dx] <= base_type::m_width); --base_type::m_step; if(npix == 0) break; npix = 0; } while(base_type::m_step >= -base_type::m_max_extent); } else { do { --base_type::m_li; base_type::m_x -= lp.inc; base_type::m_y = (base_type::m_lp->y1 + base_type::m_li.y()) >> line_subpixel_shift; if(lp.inc > 0) m_di.dec_x(base_type::m_y - base_type::m_old_y); else m_di.inc_x(base_type::m_y - base_type::m_old_y); base_type::m_old_y = base_type::m_y; dist1_start = dist2_start = m_di.dist_start(); int dy = 0; if(dist1_start < 0) ++npix; do { dist1_start -= m_di.dx_start(); dist2_start += m_di.dx_start(); if(dist1_start < 0) ++npix; if(dist2_start < 0) ++npix; ++dy; } while(base_type::m_dist[dy] <= base_type::m_width); --base_type::m_step; if(npix == 0) break; npix = 0; } while(base_type::m_step >= -base_type::m_max_extent); } base_type::m_li.adjust_forward(); } //--------------------------------------------------------------------- bool step_hor() { int dist_start; int dist; int dy; int s1 = base_type::step_hor_base(m_di); dist_start = m_di.dist_start(); cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2; cover_type* p1 = p0; *p1 = 0; if(dist_start <= 0) { *p1 = (cover_type)base_type::m_ren.cover(s1); } ++p1; dy = 1; while((dist = base_type::m_dist[dy] - s1) <= base_type::m_width) { dist_start -= m_di.dx_start(); *p1 = 0; if(dist_start <= 0) { *p1 = (cover_type)base_type::m_ren.cover(dist); } ++p1; ++dy; } dy = 1; dist_start = m_di.dist_start(); while((dist = base_type::m_dist[dy] + s1) <= base_type::m_width) { dist_start += m_di.dx_start(); *--p0 = 0; if(dist_start <= 0) { *p0 = (cover_type)base_type::m_ren.cover(dist); } ++dy; } base_type::m_ren.blend_solid_vspan(base_type::m_x, base_type::m_y - dy + 1, unsigned(p1 - p0), p0); return ++base_type::m_step < base_type::m_count; } //--------------------------------------------------------------------- bool step_ver() { int dist_start; int dist; int dx; int s1 = base_type::step_ver_base(m_di); cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2; cover_type* p1 = p0; dist_start = m_di.dist_start(); *p1 = 0; if(dist_start <= 0) { *p1 = (cover_type)base_type::m_ren.cover(s1); } ++p1; dx = 1; while((dist = base_type::m_dist[dx] - s1) <= base_type::m_width) { dist_start += m_di.dy_start(); *p1 = 0; if(dist_start <= 0) { *p1 = (cover_type)base_type::m_ren.cover(dist); } ++p1; ++dx; } dx = 1; dist_start = m_di.dist_start(); while((dist = base_type::m_dist[dx] + s1) <= base_type::m_width) { dist_start -= m_di.dy_start(); *--p0 = 0; if(dist_start <= 0) { *p0 = (cover_type)base_type::m_ren.cover(dist); } ++dx; } base_type::m_ren.blend_solid_hspan(base_type::m_x - dx + 1, base_type::m_y, unsigned(p1 - p0), p0); return ++base_type::m_step < base_type::m_count; } private: line_interpolator_aa1(const line_interpolator_aa1&); const line_interpolator_aa1& operator = (const line_interpolator_aa1&); //--------------------------------------------------------------------- distance_interpolator2 m_di; }; //====================================================line_interpolator_aa2 template class line_interpolator_aa2 : public line_interpolator_aa_base { public: typedef Renderer renderer_type; typedef typename Renderer::color_type color_type; typedef line_interpolator_aa_base base_type; //--------------------------------------------------------------------- line_interpolator_aa2(renderer_type& ren, const line_parameters& lp, int ex, int ey) : line_interpolator_aa_base(ren, lp), m_di(lp.x1, lp.y1, lp.x2, lp.y2, ex, ey, lp.x1 & ~line_subpixel_mask, lp.y1 & ~line_subpixel_mask, 0) { base_type::m_li.adjust_forward(); base_type::m_step -= base_type::m_max_extent; } //--------------------------------------------------------------------- bool step_hor() { int dist_end; int dist; int dy; int s1 = base_type::step_hor_base(m_di); cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2; cover_type* p1 = p0; dist_end = m_di.dist_end(); int npix = 0; *p1 = 0; if(dist_end > 0) { *p1 = (cover_type)base_type::m_ren.cover(s1); ++npix; } ++p1; dy = 1; while((dist = base_type::m_dist[dy] - s1) <= base_type::m_width) { dist_end -= m_di.dx_end(); *p1 = 0; if(dist_end > 0) { *p1 = (cover_type)base_type::m_ren.cover(dist); ++npix; } ++p1; ++dy; } dy = 1; dist_end = m_di.dist_end(); while((dist = base_type::m_dist[dy] + s1) <= base_type::m_width) { dist_end += m_di.dx_end(); *--p0 = 0; if(dist_end > 0) { *p0 = (cover_type)base_type::m_ren.cover(dist); ++npix; } ++dy; } base_type::m_ren.blend_solid_vspan(base_type::m_x, base_type::m_y - dy + 1, unsigned(p1 - p0), p0); return npix && ++base_type::m_step < base_type::m_count; } //--------------------------------------------------------------------- bool step_ver() { int dist_end; int dist; int dx; int s1 = base_type::step_ver_base(m_di); cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2; cover_type* p1 = p0; dist_end = m_di.dist_end(); int npix = 0; *p1 = 0; if(dist_end > 0) { *p1 = (cover_type)base_type::m_ren.cover(s1); ++npix; } ++p1; dx = 1; while((dist = base_type::m_dist[dx] - s1) <= base_type::m_width) { dist_end += m_di.dy_end(); *p1 = 0; if(dist_end > 0) { *p1 = (cover_type)base_type::m_ren.cover(dist); ++npix; } ++p1; ++dx; } dx = 1; dist_end = m_di.dist_end(); while((dist = base_type::m_dist[dx] + s1) <= base_type::m_width) { dist_end -= m_di.dy_end(); *--p0 = 0; if(dist_end > 0) { *p0 = (cover_type)base_type::m_ren.cover(dist); ++npix; } ++dx; } base_type::m_ren.blend_solid_hspan(base_type::m_x - dx + 1, base_type::m_y, unsigned(p1 - p0), p0); return npix && ++base_type::m_step < base_type::m_count; } private: line_interpolator_aa2(const line_interpolator_aa2&); const line_interpolator_aa2& operator = (const line_interpolator_aa2&); //--------------------------------------------------------------------- distance_interpolator2 m_di; }; //====================================================line_interpolator_aa3 template class line_interpolator_aa3 : public line_interpolator_aa_base { public: typedef Renderer renderer_type; typedef typename Renderer::color_type color_type; typedef line_interpolator_aa_base base_type; //--------------------------------------------------------------------- line_interpolator_aa3(renderer_type& ren, const line_parameters& lp, int sx, int sy, int ex, int ey) : line_interpolator_aa_base(ren, lp), m_di(lp.x1, lp.y1, lp.x2, lp.y2, sx, sy, ex, ey, lp.x1 & ~line_subpixel_mask, lp.y1 & ~line_subpixel_mask) { int dist1_start; int dist2_start; int npix = 1; if(lp.vertical) { do { --base_type::m_li; base_type::m_y -= lp.inc; base_type::m_x = (base_type::m_lp->x1 + base_type::m_li.y()) >> line_subpixel_shift; if(lp.inc > 0) m_di.dec_y(base_type::m_x - base_type::m_old_x); else m_di.inc_y(base_type::m_x - base_type::m_old_x); base_type::m_old_x = base_type::m_x; dist1_start = dist2_start = m_di.dist_start(); int dx = 0; if(dist1_start < 0) ++npix; do { dist1_start += m_di.dy_start(); dist2_start -= m_di.dy_start(); if(dist1_start < 0) ++npix; if(dist2_start < 0) ++npix; ++dx; } while(base_type::m_dist[dx] <= base_type::m_width); if(npix == 0) break; npix = 0; } while(--base_type::m_step >= -base_type::m_max_extent); } else { do { --base_type::m_li; base_type::m_x -= lp.inc; base_type::m_y = (base_type::m_lp->y1 + base_type::m_li.y()) >> line_subpixel_shift; if(lp.inc > 0) m_di.dec_x(base_type::m_y - base_type::m_old_y); else m_di.inc_x(base_type::m_y - base_type::m_old_y); base_type::m_old_y = base_type::m_y; dist1_start = dist2_start = m_di.dist_start(); int dy = 0; if(dist1_start < 0) ++npix; do { dist1_start -= m_di.dx_start(); dist2_start += m_di.dx_start(); if(dist1_start < 0) ++npix; if(dist2_start < 0) ++npix; ++dy; } while(base_type::m_dist[dy] <= base_type::m_width); if(npix == 0) break; npix = 0; } while(--base_type::m_step >= -base_type::m_max_extent); } base_type::m_li.adjust_forward(); base_type::m_step -= base_type::m_max_extent; } //--------------------------------------------------------------------- bool step_hor() { int dist_start; int dist_end; int dist; int dy; int s1 = base_type::step_hor_base(m_di); cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2; cover_type* p1 = p0; dist_start = m_di.dist_start(); dist_end = m_di.dist_end(); int npix = 0; *p1 = 0; if(dist_end > 0) { if(dist_start <= 0) { *p1 = (cover_type)base_type::m_ren.cover(s1); } ++npix; } ++p1; dy = 1; while((dist = base_type::m_dist[dy] - s1) <= base_type::m_width) { dist_start -= m_di.dx_start(); dist_end -= m_di.dx_end(); *p1 = 0; if(dist_end > 0 && dist_start <= 0) { *p1 = (cover_type)base_type::m_ren.cover(dist); ++npix; } ++p1; ++dy; } dy = 1; dist_start = m_di.dist_start(); dist_end = m_di.dist_end(); while((dist = base_type::m_dist[dy] + s1) <= base_type::m_width) { dist_start += m_di.dx_start(); dist_end += m_di.dx_end(); *--p0 = 0; if(dist_end > 0 && dist_start <= 0) { *p0 = (cover_type)base_type::m_ren.cover(dist); ++npix; } ++dy; } base_type::m_ren.blend_solid_vspan(base_type::m_x, base_type::m_y - dy + 1, unsigned(p1 - p0), p0); return npix && ++base_type::m_step < base_type::m_count; } //--------------------------------------------------------------------- bool step_ver() { int dist_start; int dist_end; int dist; int dx; int s1 = base_type::step_ver_base(m_di); cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2; cover_type* p1 = p0; dist_start = m_di.dist_start(); dist_end = m_di.dist_end(); int npix = 0; *p1 = 0; if(dist_end > 0) { if(dist_start <= 0) { *p1 = (cover_type)base_type::m_ren.cover(s1); } ++npix; } ++p1; dx = 1; while((dist = base_type::m_dist[dx] - s1) <= base_type::m_width) { dist_start += m_di.dy_start(); dist_end += m_di.dy_end(); *p1 = 0; if(dist_end > 0 && dist_start <= 0) { *p1 = (cover_type)base_type::m_ren.cover(dist); ++npix; } ++p1; ++dx; } dx = 1; dist_start = m_di.dist_start(); dist_end = m_di.dist_end(); while((dist = base_type::m_dist[dx] + s1) <= base_type::m_width) { dist_start -= m_di.dy_start(); dist_end -= m_di.dy_end(); *--p0 = 0; if(dist_end > 0 && dist_start <= 0) { *p0 = (cover_type)base_type::m_ren.cover(dist); ++npix; } ++dx; } base_type::m_ren.blend_solid_hspan(base_type::m_x - dx + 1, base_type::m_y, unsigned(p1 - p0), p0); return npix && ++base_type::m_step < base_type::m_count; } private: line_interpolator_aa3(const line_interpolator_aa3&); const line_interpolator_aa3& operator = (const line_interpolator_aa3&); //--------------------------------------------------------------------- distance_interpolator3 m_di; }; //==========================================================line_profile_aa // // See Implementation agg_line_profile_aa.cpp // class line_profile_aa { public: //--------------------------------------------------------------------- typedef int8u value_type; enum { subpixel_shift = line_subpixel_shift, subpixel_size = 1 << subpixel_shift, subpixel_mask = subpixel_size - 1 }; enum { aa_shift = 8, aa_num = 1 << aa_shift, aa_mask = aa_num - 1 }; //--------------------------------------------------------------------- ~line_profile_aa() { delete [] m_profile; } //--------------------------------------------------------------------- line_profile_aa() : m_size(0), m_profile(0), m_subpixel_width(0), m_min_width(1.0), m_smoother_width(1.0) { int i; for(i = 0; i < aa_num; i++) m_gamma[i] = (value_type)i; } //--------------------------------------------------------------------- template line_profile_aa(double w, const GammaF& gamma_function) : m_size(0), m_profile(0), m_subpixel_width(0), m_min_width(1.0), m_smoother_width(1.0) { gamma(gamma_function); width(w); } //--------------------------------------------------------------------- void min_width(double w) { m_min_width = w; } void smoother_width(double w) { m_smoother_width = w; } //--------------------------------------------------------------------- template void gamma(const GammaF& gamma_function) { int i; for(i = 0; i < aa_num; i++) { m_gamma[i] = value_type( floor( gamma_function(double(i) / aa_mask) * aa_mask + 0.5)); } } void width(double w); unsigned profile_size() const { return m_size; } int subpixel_width() const { return m_subpixel_width; } //--------------------------------------------------------------------- double min_width() const { return m_min_width; } double smoother_width() const { return m_smoother_width; } //--------------------------------------------------------------------- value_type value(int dist) const { return m_profile[dist + subpixel_size*2]; } private: line_profile_aa(const line_profile_aa&); const line_profile_aa& operator = (const line_profile_aa&); value_type* profile(double w); void set(double center_width, double smoother_width); //--------------------------------------------------------------------- unsigned m_size; value_type* m_profile; value_type m_gamma[aa_num]; int m_subpixel_width; double m_min_width; double m_smoother_width; }; //======================================================renderer_outline_aa template class renderer_outline_aa { public: //--------------------------------------------------------------------- typedef BaseRenderer base_ren_type; typedef renderer_outline_aa self_type; typedef typename base_ren_type::color_type color_type; //--------------------------------------------------------------------- renderer_outline_aa(base_ren_type& ren, line_profile_aa& prof) : m_ren(&ren), m_profile(&prof) { } //--------------------------------------------------------------------- void color(const color_type& c) { m_color = c; } const color_type& color() const { return m_color; } //--------------------------------------------------------------------- void profile(const line_profile_aa& prof) { m_profile = &prof; } const line_profile_aa& profile() const { return *m_profile; } line_profile_aa& profile() { return *m_profile; } //--------------------------------------------------------------------- int subpixel_width() const { return m_profile->subpixel_width(); } //--------------------------------------------------------------------- int cover(int d) const { return m_profile->value(d); } //------------------------------------------------------------------------- void blend_solid_hspan(int x, int y, unsigned len, const cover_type* covers) { m_ren->blend_solid_hspan(x, y, len, m_color, covers); } //------------------------------------------------------------------------- void blend_solid_vspan(int x, int y, unsigned len, const cover_type* covers) { m_ren->blend_solid_vspan(x, y, len, m_color, covers); } //------------------------------------------------------------------------- static bool accurate_join_only() { return false; } //------------------------------------------------------------------------- template void semidot_hline(Cmp cmp, int xc1, int yc1, int xc2, int yc2, int x1, int y1, int x2) { cover_type covers[line_interpolator_aa_base::max_half_width * 2 + 4]; cover_type* p0 = covers; cover_type* p1 = covers; int x = x1 << line_subpixel_shift; int y = y1 << line_subpixel_shift; int w = subpixel_width(); distance_interpolator0 di(xc1, yc1, xc2, yc2, x, y); x += line_subpixel_size/2; y += line_subpixel_size/2; int x0 = x1; int dx = x - xc1; int dy = y - yc1; do { int d = int(fast_sqrt(dx*dx + dy*dy)); *p1 = 0; if(cmp(di.dist()) && d <= w) { *p1 = (cover_type)cover(d); } ++p1; dx += line_subpixel_size; di.inc_x(); } while(++x1 <= x2); m_ren->blend_solid_hspan(x0, y1, unsigned(p1 - p0), color(), p0); } //------------------------------------------------------------------------- template void semidot(Cmp cmp, int xc1, int yc1, int xc2, int yc2) { int r = ((subpixel_width() + line_subpixel_mask) >> line_subpixel_shift); if(r < 1) r = 1; ellipse_bresenham_interpolator ei(r, r); int dx = 0; int dy = -r; int dy0 = dy; int dx0 = dx; int x = xc1 >> line_subpixel_shift; int y = yc1 >> line_subpixel_shift; do { dx += ei.dx(); dy += ei.dy(); if(dy != dy0) { semidot_hline(cmp, xc1, yc1, xc2, yc2, x-dx0, y+dy0, x+dx0); semidot_hline(cmp, xc1, yc1, xc2, yc2, x-dx0, y-dy0, x+dx0); } dx0 = dx; dy0 = dy; ++ei; } while(dy < 0); semidot_hline(cmp, xc1, yc1, xc2, yc2, x-dx0, y+dy0, x+dx0); } //------------------------------------------------------------------------- void line0(const line_parameters& lp) { line_interpolator_aa0 li(*this, lp); if(li.count()) { if(li.vertical()) { while(li.step_ver()); } else { while(li.step_hor()); } } } //------------------------------------------------------------------------- void line1(const line_parameters& lp, int sx, int sy) { line_interpolator_aa1 li(*this, lp, sx, sy); if(li.vertical()) { while(li.step_ver()); } else { while(li.step_hor()); } } //------------------------------------------------------------------------- void line2(const line_parameters& lp, int ex, int ey) { line_interpolator_aa2 li(*this, lp, ex, ey); if(li.vertical()) { while(li.step_ver()); } else { while(li.step_hor()); } } //------------------------------------------------------------------------- void line3(const line_parameters& lp, int sx, int sy, int ex, int ey) { line_interpolator_aa3 li(*this, lp, sx, sy, ex, ey); if(li.vertical()) { while(li.step_ver()); } else { while(li.step_hor()); } } private: base_ren_type* m_ren; line_profile_aa* m_profile; color_type m_color; }; } #endif aggdraw-1.3.14/agg2/include/agg_renderer_outline_image.h000066400000000000000000000743161417726601400232000ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_RENDERER_OUTLINE_IMAGE_INCLUDED #define AGG_RENDERER_OUTLINE_IMAGE_INCLUDED #include #include "agg_line_aa_basics.h" #include "agg_dda_line.h" #include "agg_rendering_buffer.h" namespace agg { //========================================================line_image_scale template class line_image_scale { public: typedef typename Source::color_type color_type; line_image_scale(const Source& src, double height) : m_source(src), m_height(height), m_scale(src.height() / height) { } double width() const { return m_source.width(); } double height() const { return m_height; } color_type pixel(int x, int y) const { double src_y = y * m_scale; int h = int(m_source.height()) - 1; int y1 = int(floor(src_y)); int y2 = y1 + 1; color_type pix1 = (y1 < 0) ? m_source.pixel(x, 0).transparent() : m_source.pixel(x, y1); color_type pix2 = (y2 > h) ? m_source.pixel(x, h).transparent() : m_source.pixel(x, y2); return pix1.gradient(pix2, src_y - y1); } private: line_image_scale(const line_image_scale&); const line_image_scale& operator = (const line_image_scale&); const Source& m_source; double m_height; double m_scale; }; //======================================================line_image_pattern template class line_image_pattern { public: typedef Filter filter_type; typedef typename filter_type::color_type color_type; //-------------------------------------------------------------------- ~line_image_pattern() { delete [] m_data; } //-------------------------------------------------------------------- line_image_pattern(const Filter& filter) : m_filter(&filter), m_dilation(filter.dilation() + 1), m_dilation_hr(m_dilation << line_subpixel_shift), m_data(0), m_width(0), m_height(0), m_width_hr(0), m_half_height_hr(0), m_offset_y_hr(0) { } // Create //-------------------------------------------------------------------- template line_image_pattern(const Filter& filter, const Source& src) : m_filter(&filter), m_dilation(filter.dilation() + 1), m_dilation_hr(m_dilation << line_subpixel_shift), m_data(0), m_width(0), m_height(0), m_width_hr(0), m_half_height_hr(0), m_offset_y_hr(0) { create(src); } // Create //-------------------------------------------------------------------- template void create(const Source& src) { m_height = unsigned(ceil((double)src.height())); m_width = unsigned(ceil((double)src.width())); m_width_hr = int(src.width() * line_subpixel_size); m_half_height_hr = int(src.height() * line_subpixel_size/2); m_offset_y_hr = m_dilation_hr + m_half_height_hr - line_subpixel_size/2; m_half_height_hr += line_subpixel_size/2; delete [] m_data; m_data = new color_type [(m_width + m_dilation * 2) * (m_height + m_dilation * 2)]; m_buf.attach(m_data, m_width + m_dilation * 2, m_height + m_dilation * 2, m_width + m_dilation * 2); unsigned x, y; color_type* d1; color_type* d2; for(y = 0; y < m_height; y++) { d1 = m_buf.row(y + m_dilation) + m_dilation; for(x = 0; x < m_width; x++) { *d1++ = src.pixel(x, y); } } const color_type* s1; const color_type* s2; for(y = 0; y < m_dilation; y++) { s1 = m_buf.row(m_height + m_dilation - 1) + m_dilation; s2 = m_buf.row(m_dilation) + m_dilation; d1 = m_buf.row(m_dilation + m_height + y) + m_dilation; d2 = m_buf.row(m_dilation - y - 1) + m_dilation; for(x = 0; x < m_width; x++) { *d1++ = color_type(*s1++, 0); *d2++ = color_type(*s2++, 0); } } unsigned h = m_height + m_dilation * 2; for(y = 0; y < h; y++) { s1 = m_buf.row(y) + m_dilation; s2 = m_buf.row(y) + m_dilation + m_width; d1 = m_buf.row(y) + m_dilation + m_width; d2 = m_buf.row(y) + m_dilation; for(x = 0; x < m_dilation; x++) { *d1++ = *s1++; *--d2 = *--s2; } } } //-------------------------------------------------------------------- int pattern_width() const { return m_width_hr; } int line_width() const { return m_half_height_hr; } //-------------------------------------------------------------------- color_type pixel(int x, int y) const { return m_filter->pixel_high_res(m_buf.rows(), x % m_width_hr + m_dilation_hr, y + m_offset_y_hr); } //-------------------------------------------------------------------- const filter_type& filter() const { return m_filter; } filter_type& filter() { return m_filter; } private: line_image_pattern(const line_image_pattern&); const line_image_pattern& operator = (const line_image_pattern&); protected: row_ptr_cache m_buf; const filter_type* m_filter; unsigned m_dilation; int m_dilation_hr; color_type* m_data; unsigned m_width; unsigned m_height; int m_width_hr; int m_half_height_hr; int m_offset_y_hr; }; //=================================================line_image_pattern_pow2 template class line_image_pattern_pow2 : public line_image_pattern { public: typedef Filter filter_type; typedef typename filter_type::color_type color_type; typedef line_image_pattern base_type; //-------------------------------------------------------------------- line_image_pattern_pow2(const Filter& filter) : line_image_pattern(filter), m_mask(line_subpixel_mask) {} //-------------------------------------------------------------------- template line_image_pattern_pow2(const Filter& filter, const Source& src) : line_image_pattern(filter), m_mask(line_subpixel_mask) { create(src); } //-------------------------------------------------------------------- template void create(const Source& src) { line_image_pattern::create(src); m_mask = 1; while(m_mask < base_type::m_width) { m_mask <<= 1; m_mask |= 1; } m_mask <<= line_subpixel_shift - 1; m_mask |= line_subpixel_mask; base_type::m_width_hr = m_mask + 1; } //-------------------------------------------------------------------- void pixel(color_type* p, int x, int y) const { base_type::m_filter->pixel_high_res( base_type::m_buf.rows(), p, (x & m_mask) + base_type::m_dilation_hr, y + base_type::m_offset_y_hr); } private: unsigned m_mask; }; //===================================================distance_interpolator4 class distance_interpolator4 { public: //--------------------------------------------------------------------- distance_interpolator4() {} distance_interpolator4(int x1, int y1, int x2, int y2, int sx, int sy, int ex, int ey, int len, double scale, int x, int y) : m_dx(x2 - x1), m_dy(y2 - y1), m_dx_start(line_mr(sx) - line_mr(x1)), m_dy_start(line_mr(sy) - line_mr(y1)), m_dx_end(line_mr(ex) - line_mr(x2)), m_dy_end(line_mr(ey) - line_mr(y2)), m_dist(int(double(x + line_subpixel_size/2 - x2) * double(m_dy) - double(y + line_subpixel_size/2 - y2) * double(m_dx))), m_dist_start((line_mr(x + line_subpixel_size/2) - line_mr(sx)) * m_dy_start - (line_mr(y + line_subpixel_size/2) - line_mr(sy)) * m_dx_start), m_dist_end((line_mr(x + line_subpixel_size/2) - line_mr(ex)) * m_dy_end - (line_mr(y + line_subpixel_size/2) - line_mr(ey)) * m_dx_end), m_len(int(len / scale)) { double d = len * scale; int dx = int(((x2 - x1) << line_subpixel_shift) / d); int dy = int(((y2 - y1) << line_subpixel_shift) / d); m_dx_pict = -dy; m_dy_pict = dx; m_dist_pict = ((x + line_subpixel_size/2 - (x1 - dy)) * m_dy_pict - (y + line_subpixel_size/2 - (y1 + dx)) * m_dx_pict) >> line_subpixel_shift; m_dx <<= line_subpixel_shift; m_dy <<= line_subpixel_shift; m_dx_start <<= line_mr_subpixel_shift; m_dy_start <<= line_mr_subpixel_shift; m_dx_end <<= line_mr_subpixel_shift; m_dy_end <<= line_mr_subpixel_shift; } //--------------------------------------------------------------------- void inc_x() { m_dist += m_dy; m_dist_start += m_dy_start; m_dist_pict += m_dy_pict; m_dist_end += m_dy_end; } //--------------------------------------------------------------------- void dec_x() { m_dist -= m_dy; m_dist_start -= m_dy_start; m_dist_pict -= m_dy_pict; m_dist_end -= m_dy_end; } //--------------------------------------------------------------------- void inc_y() { m_dist -= m_dx; m_dist_start -= m_dx_start; m_dist_pict -= m_dx_pict; m_dist_end -= m_dx_end; } //--------------------------------------------------------------------- void dec_y() { m_dist += m_dx; m_dist_start += m_dx_start; m_dist_pict += m_dx_pict; m_dist_end += m_dx_end; } //--------------------------------------------------------------------- void inc_x(int dy) { m_dist += m_dy; m_dist_start += m_dy_start; m_dist_pict += m_dy_pict; m_dist_end += m_dy_end; if(dy > 0) { m_dist -= m_dx; m_dist_start -= m_dx_start; m_dist_pict -= m_dx_pict; m_dist_end -= m_dx_end; } if(dy < 0) { m_dist += m_dx; m_dist_start += m_dx_start; m_dist_pict += m_dx_pict; m_dist_end += m_dx_end; } } //--------------------------------------------------------------------- void dec_x(int dy) { m_dist -= m_dy; m_dist_start -= m_dy_start; m_dist_pict -= m_dy_pict; m_dist_end -= m_dy_end; if(dy > 0) { m_dist -= m_dx; m_dist_start -= m_dx_start; m_dist_pict -= m_dx_pict; m_dist_end -= m_dx_end; } if(dy < 0) { m_dist += m_dx; m_dist_start += m_dx_start; m_dist_pict += m_dx_pict; m_dist_end += m_dx_end; } } //--------------------------------------------------------------------- void inc_y(int dx) { m_dist -= m_dx; m_dist_start -= m_dx_start; m_dist_pict -= m_dx_pict; m_dist_end -= m_dx_end; if(dx > 0) { m_dist += m_dy; m_dist_start += m_dy_start; m_dist_pict += m_dy_pict; m_dist_end += m_dy_end; } if(dx < 0) { m_dist -= m_dy; m_dist_start -= m_dy_start; m_dist_pict -= m_dy_pict; m_dist_end -= m_dy_end; } } //--------------------------------------------------------------------- void dec_y(int dx) { m_dist += m_dx; m_dist_start += m_dx_start; m_dist_pict += m_dx_pict; m_dist_end += m_dx_end; if(dx > 0) { m_dist += m_dy; m_dist_start += m_dy_start; m_dist_pict += m_dy_pict; m_dist_end += m_dy_end; } if(dx < 0) { m_dist -= m_dy; m_dist_start -= m_dy_start; m_dist_pict -= m_dy_pict; m_dist_end -= m_dy_end; } } //--------------------------------------------------------------------- int dist() const { return m_dist; } int dist_start() const { return m_dist_start; } int dist_pict() const { return m_dist_pict; } int dist_end() const { return m_dist_end; } //--------------------------------------------------------------------- int dx() const { return m_dx; } int dy() const { return m_dy; } int dx_start() const { return m_dx_start; } int dy_start() const { return m_dy_start; } int dx_pict() const { return m_dx_pict; } int dy_pict() const { return m_dy_pict; } int dx_end() const { return m_dx_end; } int dy_end() const { return m_dy_end; } int len() const { return m_len; } private: //--------------------------------------------------------------------- int m_dx; int m_dy; int m_dx_start; int m_dy_start; int m_dx_pict; int m_dy_pict; int m_dx_end; int m_dy_end; int m_dist; int m_dist_start; int m_dist_pict; int m_dist_end; int m_len; }; //==================================================line_interpolator_image template class line_interpolator_image { public: typedef Renderer renderer_type; typedef typename Renderer::color_type color_type; //--------------------------------------------------------------------- enum { max_half_width = 64 }; //--------------------------------------------------------------------- line_interpolator_image(renderer_type& ren, const line_parameters& lp, int sx, int sy, int ex, int ey, int pattern_start, double scale_x) : m_lp(lp), m_li(lp.vertical ? line_dbl_hr(lp.x2 - lp.x1) : line_dbl_hr(lp.y2 - lp.y1), lp.vertical ? abs(lp.y2 - lp.y1) : abs(lp.x2 - lp.x1) + 1), m_di(lp.x1, lp.y1, lp.x2, lp.y2, sx, sy, ex, ey, lp.len, scale_x, lp.x1 & ~line_subpixel_mask, lp.y1 & ~line_subpixel_mask), m_ren(ren), m_x(lp.x1 >> line_subpixel_shift), m_y(lp.y1 >> line_subpixel_shift), m_old_x(m_x), m_old_y(m_y), m_count((lp.vertical ? abs((lp.y2 >> line_subpixel_shift) - m_y) : abs((lp.x2 >> line_subpixel_shift) - m_x))), m_width(ren.subpixel_width()), m_max_extent(m_width >> (line_subpixel_shift - 2)), m_start(pattern_start + (m_max_extent + 2) * ren.pattern_width()), m_step(0) { agg::dda2_line_interpolator li(0, lp.vertical ? (lp.dy << agg::line_subpixel_shift) : (lp.dx << agg::line_subpixel_shift), lp.len); unsigned i; int stop = m_width + line_subpixel_size * 2; for(i = 0; i < max_half_width; ++i) { m_dist_pos[i] = li.y(); if(m_dist_pos[i] >= stop) break; ++li; } m_dist_pos[i] = 0x7FFF0000; int dist1_start; int dist2_start; int npix = 1; if(lp.vertical) { do { --m_li; m_y -= lp.inc; m_x = (m_lp.x1 + m_li.y()) >> line_subpixel_shift; if(lp.inc > 0) m_di.dec_y(m_x - m_old_x); else m_di.inc_y(m_x - m_old_x); m_old_x = m_x; dist1_start = dist2_start = m_di.dist_start(); int dx = 0; if(dist1_start < 0) ++npix; do { dist1_start += m_di.dy_start(); dist2_start -= m_di.dy_start(); if(dist1_start < 0) ++npix; if(dist2_start < 0) ++npix; ++dx; } while(m_dist_pos[dx] <= m_width); if(npix == 0) break; npix = 0; } while(--m_step >= -m_max_extent); } else { do { --m_li; m_x -= lp.inc; m_y = (m_lp.y1 + m_li.y()) >> line_subpixel_shift; if(lp.inc > 0) m_di.dec_x(m_y - m_old_y); else m_di.inc_x(m_y - m_old_y); m_old_y = m_y; dist1_start = dist2_start = m_di.dist_start(); int dy = 0; if(dist1_start < 0) ++npix; do { dist1_start -= m_di.dx_start(); dist2_start += m_di.dx_start(); if(dist1_start < 0) ++npix; if(dist2_start < 0) ++npix; ++dy; } while(m_dist_pos[dy] <= m_width); if(npix == 0) break; npix = 0; } while(--m_step >= -m_max_extent); } m_li.adjust_forward(); m_step -= m_max_extent; } //--------------------------------------------------------------------- bool step_hor() { ++m_li; m_x += m_lp.inc; m_y = (m_lp.y1 + m_li.y()) >> line_subpixel_shift; if(m_lp.inc > 0) m_di.inc_x(m_y - m_old_y); else m_di.dec_x(m_y - m_old_y); m_old_y = m_y; int s1 = m_di.dist() / m_lp.len; int s2 = -s1; if(m_lp.inc < 0) s1 = -s1; int dist_start; int dist_pict; int dist_end; int dy; int dist; dist_start = m_di.dist_start(); dist_pict = m_di.dist_pict() + m_start; dist_end = m_di.dist_end(); color_type* p0 = m_colors + max_half_width + 2; color_type* p1 = p0; int npix = 0; p1->clear(); if(dist_end > 0) { if(dist_start <= 0) { m_ren.pixel(p1, dist_pict, s2); } ++npix; } ++p1; dy = 1; while((dist = m_dist_pos[dy]) - s1 <= m_width) { dist_start -= m_di.dx_start(); dist_pict -= m_di.dx_pict(); dist_end -= m_di.dx_end(); p1->clear(); if(dist_end > 0 && dist_start <= 0) { if(m_lp.inc > 0) dist = -dist; m_ren.pixel(p1, dist_pict, s2 - dist); ++npix; } ++p1; ++dy; } dy = 1; dist_start = m_di.dist_start(); dist_pict = m_di.dist_pict() + m_start; dist_end = m_di.dist_end(); while((dist = m_dist_pos[dy]) + s1 <= m_width) { dist_start += m_di.dx_start(); dist_pict += m_di.dx_pict(); dist_end += m_di.dx_end(); --p0; p0->clear(); if(dist_end > 0 && dist_start <= 0) { if(m_lp.inc > 0) dist = -dist; m_ren.pixel(p0, dist_pict, s2 + dist); ++npix; } ++dy; } m_ren.blend_color_vspan(m_x, m_y - dy + 1, unsigned(p1 - p0), p0); return npix && ++m_step < m_count; } //--------------------------------------------------------------------- bool step_ver() { ++m_li; m_y += m_lp.inc; m_x = (m_lp.x1 + m_li.y()) >> line_subpixel_shift; if(m_lp.inc > 0) m_di.inc_y(m_x - m_old_x); else m_di.dec_y(m_x - m_old_x); m_old_x = m_x; int s1 = m_di.dist() / m_lp.len; int s2 = -s1; if(m_lp.inc > 0) s1 = -s1; int dist_start; int dist_pict; int dist_end; int dist; int dx; dist_start = m_di.dist_start(); dist_pict = m_di.dist_pict() + m_start; dist_end = m_di.dist_end(); color_type* p0 = m_colors + max_half_width + 2; color_type* p1 = p0; int npix = 0; p1->clear(); if(dist_end > 0) { if(dist_start <= 0) { m_ren.pixel(p1, dist_pict, s2); } ++npix; } ++p1; dx = 1; while((dist = m_dist_pos[dx]) - s1 <= m_width) { dist_start += m_di.dy_start(); dist_pict += m_di.dy_pict(); dist_end += m_di.dy_end(); p1->clear(); if(dist_end > 0 && dist_start <= 0) { if(m_lp.inc > 0) dist = -dist; m_ren.pixel(p1, dist_pict, s2 + dist); ++npix; } ++p1; ++dx; } dx = 1; dist_start = m_di.dist_start(); dist_pict = m_di.dist_pict() + m_start; dist_end = m_di.dist_end(); while((dist = m_dist_pos[dx]) + s1 <= m_width) { dist_start -= m_di.dy_start(); dist_pict -= m_di.dy_pict(); dist_end -= m_di.dy_end(); --p0; p0->clear(); if(dist_end > 0 && dist_start <= 0) { if(m_lp.inc > 0) dist = -dist; m_ren.pixel(p0, dist_pict, s2 - dist); ++npix; } ++dx; } m_ren.blend_color_hspan(m_x - dx + 1, m_y, unsigned(p1 - p0), p0); return npix && ++m_step < m_count; } //--------------------------------------------------------------------- int pattern_end() const { return m_start + m_di.len(); } //--------------------------------------------------------------------- bool vertical() const { return m_lp.vertical; } int width() const { return m_width; } int count() const { return m_count; } private: line_interpolator_image(const line_interpolator_image&); const line_interpolator_image& operator = (const line_interpolator_image&); protected: const line_parameters& m_lp; dda2_line_interpolator m_li; distance_interpolator4 m_di; renderer_type& m_ren; int m_plen; int m_x; int m_y; int m_old_x; int m_old_y; int m_count; int m_width; int m_max_extent; int m_start; int m_step; int m_dist_pos[max_half_width + 1]; color_type m_colors[max_half_width * 2 + 4]; }; //===================================================renderer_outline_image template class renderer_outline_image { public: //--------------------------------------------------------------------- typedef BaseRenderer base_ren_type; typedef renderer_outline_image self_type; typedef typename base_ren_type::color_type color_type; typedef ImagePattern pattern_type; //--------------------------------------------------------------------- renderer_outline_image(base_ren_type& ren, const pattern_type& patt) : m_ren(&ren), m_pattern(&patt), m_start(0), m_scale_x(1.0) { } //--------------------------------------------------------------------- void pattern(const pattern_type& p) { m_pattern = &p; } const pattern_type& pattern() const { return *m_pattern; } //--------------------------------------------------------------------- void scale_x(double s) { m_scale_x = s; } double scale_x() const { return m_scale_x; } //--------------------------------------------------------------------- int subpixel_width() const { return m_pattern->line_width(); } int pattern_width() const { return m_pattern->pattern_width(); } //------------------------------------------------------------------------- void pixel(color_type* p, int x, int y) const { m_pattern->pixel(p, x, y); } //------------------------------------------------------------------------- void blend_color_hspan(int x, int y, unsigned len, const color_type* colors) { m_ren->blend_color_hspan(x, y, len, colors, 0); } //------------------------------------------------------------------------- void blend_color_vspan(int x, int y, unsigned len, const color_type* colors) { m_ren->blend_color_vspan(x, y, len, colors, 0); } //------------------------------------------------------------------------- static bool accurate_join_only() { return true; } //------------------------------------------------------------------------- template void semidot(Cmp, int, int, int, int) { } //------------------------------------------------------------------------- void line0(const line_parameters&) { } //------------------------------------------------------------------------- void line1(const line_parameters&, int, int) { } //------------------------------------------------------------------------- void line2(const line_parameters&, int, int) { } //------------------------------------------------------------------------- void line3(const line_parameters& lp, int sx, int sy, int ex, int ey) { line_interpolator_image li(*this, lp, sx, sy, ex, ey, m_start, m_scale_x); if(li.vertical()) { while(li.step_ver()); } else { while(li.step_hor()); } m_start = li.pattern_end(); } private: base_ren_type* m_ren; const pattern_type* m_pattern; int m_start; double m_scale_x; }; } #endif aggdraw-1.3.14/agg2/include/agg_renderer_primitives.h000066400000000000000000000170771417726601400225530ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // class renderer_primitives // //---------------------------------------------------------------------------- #ifndef AGG_RENDERER_PRIMITIVES_INCLUDED #define AGG_RENDERER_PRIMITIVES_INCLUDED #include "agg_basics.h" #include "agg_renderer_base.h" #include "agg_dda_line.h" #include "agg_ellipse_bresenham.h" namespace agg { //-----------------------------------------------------renderer_primitives template class renderer_primitives { public: typedef BaseRenderer base_ren_type; typedef typename base_ren_type::color_type color_type; //-------------------------------------------------------------------- renderer_primitives(base_ren_type& ren) : m_ren(&ren), m_fill_color(), m_line_color(), m_curr_x(0), m_curr_y(0) { } //-------------------------------------------------------------------- static int coord(double c) { return int(c * line_bresenham_interpolator::subpixel_size); } //-------------------------------------------------------------------- void fill_color(const color_type& c) { m_fill_color = c; } void line_color(const color_type& c) { m_line_color = c; } const color_type& fill_color() const { return m_fill_color; } const color_type& line_color() const { return m_line_color; } //-------------------------------------------------------------------- void rectangle(int x1, int y1, int x2, int y2) { m_ren->blend_hline(x1, y1, x2-1, m_line_color, cover_full); m_ren->blend_vline(x2, y1, y2-1, m_line_color, cover_full); m_ren->blend_hline(x1+1, y2, x2, m_line_color, cover_full); m_ren->blend_vline(x1, y1+1, y2, m_line_color, cover_full); } //-------------------------------------------------------------------- void solid_rectangle(int x1, int y1, int x2, int y2) { m_ren->blend_bar(x1, y1, x2, y2, m_fill_color, cover_full); } //-------------------------------------------------------------------- void outlined_rectangle(int x1, int y1, int x2, int y2) { rectangle(x1, y1, x2, y2); m_ren->blend_bar(x1+1, y1+1, x2-1, y2-1, m_fill_color, cover_full); } //-------------------------------------------------------------------- void ellipse(int x, int y, int rx, int ry) { ellipse_bresenham_interpolator ei(rx, ry); int dx = 0; int dy = -ry; do { dx += ei.dx(); dy += ei.dy(); m_ren->blend_pixel(x + dx, y + dy, m_line_color, cover_full); m_ren->blend_pixel(x + dx, y - dy, m_line_color, cover_full); m_ren->blend_pixel(x - dx, y - dy, m_line_color, cover_full); m_ren->blend_pixel(x - dx, y + dy, m_line_color, cover_full); ++ei; } while(dy < 0); } //-------------------------------------------------------------------- void solid_ellipse(int x, int y, int rx, int ry) { ellipse_bresenham_interpolator ei(rx, ry); int dx = 0; int dy = -ry; int dy0 = dy; int dx0 = dx; do { dx += ei.dx(); dy += ei.dy(); if(dy != dy0) { m_ren->blend_hline(x-dx0, y+dy0, x+dx0, m_fill_color, cover_full); m_ren->blend_hline(x-dx0, y-dy0, x+dx0, m_fill_color, cover_full); } dx0 = dx; dy0 = dy; ++ei; } while(dy < 0); m_ren->blend_hline(x-dx0, y+dy0, x+dx0, m_fill_color, cover_full); } //-------------------------------------------------------------------- void outlined_ellipse(int x, int y, int rx, int ry) { ellipse_bresenham_interpolator ei(rx, ry); int dx = 0; int dy = -ry; do { dx += ei.dx(); dy += ei.dy(); m_ren->blend_pixel(x + dx, y + dy, m_line_color, cover_full); m_ren->blend_pixel(x + dx, y - dy, m_line_color, cover_full); m_ren->blend_pixel(x - dx, y - dy, m_line_color, cover_full); m_ren->blend_pixel(x - dx, y + dy, m_line_color, cover_full); if(ei.dy() && dx) { m_ren->blend_hline(x-dx+1, y+dy, x+dx-1, m_fill_color, cover_full); m_ren->blend_hline(x-dx+1, y-dy, x+dx-1, m_fill_color, cover_full); } ++ei; } while(dy < 0); } //-------------------------------------------------------------------- void line(int x1, int y1, int x2, int y2, bool last=false) { line_bresenham_interpolator li(x1, y1, x2, y2); unsigned len = li.len(); if(len == 0) { if(last) { m_ren->blend_pixel(li.line_lr(x1), li.line_lr(y1), m_line_color, cover_full); } return; } if(last) ++len; if(li.is_ver()) { do { m_ren->blend_pixel(li.x2(), li.y1(), m_line_color, cover_full); li.vstep(); } while(--len); } else { do { m_ren->blend_pixel(li.x1(), li.y2(), m_line_color, cover_full); li.hstep(); } while(--len); } } //-------------------------------------------------------------------- void move_to(int x, int y) { m_curr_x = x; m_curr_y = y; } //-------------------------------------------------------------------- void line_to(int x, int y, bool last=false) { line(m_curr_x, m_curr_y, x, y, last); m_curr_x = x; m_curr_y = y; } //-------------------------------------------------------------------- const base_ren_type& ren() const { return *m_ren; } base_ren_type& ren() { return *m_ren; } //-------------------------------------------------------------------- const rendering_buffer& rbuf() const { return m_ren->rbuf(); } rendering_buffer& rbuf() { return m_ren->rbuf(); } private: base_ren_type* m_ren; color_type m_fill_color; color_type m_line_color; int m_curr_x; int m_curr_y; }; } #endif aggdraw-1.3.14/agg2/include/agg_renderer_raster_text.h000066400000000000000000000207661417726601400227230ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_RENDERER_RASTER_TEXT_INCLUDED #define AGG_RENDERER_RASTER_TEXT_INCLUDED #include "agg_basics.h" namespace agg { //==============================================renderer_raster_htext_solid template class renderer_raster_htext_solid { public: typedef BaseRenderer ren_type; typedef GlyphGenerator glyph_gen_type; typedef typename glyph_gen_type::glyph_rect glyph_rect; typedef typename ren_type::color_type color_type; renderer_raster_htext_solid(ren_type& ren, glyph_gen_type& glyph) : m_ren(&ren), m_glyph(&glyph) { } //-------------------------------------------------------------------- void color(const color_type& c) { m_color = c; } const color_type& color() const { return m_color; } //-------------------------------------------------------------------- template void render_text(double x, double y, const CharT* str, bool flip=false) { glyph_rect r; while(*str) { m_glyph->prepare(&r, x, y, *str, flip); if(r.x2 >= r.x1) { int i; if(flip) { for(i = r.y1; i <= r.y2; i++) { m_ren->blend_solid_hspan(r.x1, i, (r.x2 - r.x1 + 1), m_color, m_glyph->span(r.y2 - i)); } } else { for(i = r.y1; i <= r.y2; i++) { m_ren->blend_solid_hspan(r.x1, i, (r.x2 - r.x1 + 1), m_color, m_glyph->span(i - r.y1)); } } } x += r.dx; y += r.dy; ++str; } } private: ren_type* m_ren; glyph_gen_type* m_glyph; color_type m_color; }; //=============================================renderer_raster_vtext_solid template class renderer_raster_vtext_solid { public: typedef BaseRenderer ren_type; typedef GlyphGenerator glyph_gen_type; typedef typename glyph_gen_type::glyph_rect glyph_rect; typedef typename ren_type::color_type color_type; renderer_raster_vtext_solid(ren_type& ren, glyph_gen_type& glyph) : m_ren(&ren), m_glyph(&glyph) { } //-------------------------------------------------------------------- void color(const color_type& c) { m_color = c; } const color_type& color() const { return m_color; } //-------------------------------------------------------------------- template void render_text(double x, double y, const CharT* str, bool flip=false) { glyph_rect r; while(*str) { m_glyph->prepare(&r, x, y, *str, !flip); if(r.x2 >= r.x1) { int i; if(flip) { for(i = r.y1; i <= r.y2; i++) { m_ren->blend_solid_vspan(i, r.x1, (r.x2 - r.x1 + 1), m_color, m_glyph->span(i - r.y1)); } } else { for(i = r.y1; i <= r.y2; i++) { m_ren->blend_solid_vspan(i, r.x1, (r.x2 - r.x1 + 1), m_color, m_glyph->span(r.y2 - i)); } } } x += r.dx; y += r.dy; ++str; } } private: ren_type* m_ren; glyph_gen_type* m_glyph; color_type m_color; }; //===================================================renderer_raster_htext template class renderer_raster_htext { public: typedef ScanlineRenderer ren_type; typedef GlyphGenerator glyph_gen_type; typedef typename glyph_gen_type::glyph_rect glyph_rect; class scanline_single_span { public: typedef agg::cover_type cover_type; //---------------------------------------------------------------- struct const_span { int x; unsigned len; const cover_type* covers; const_span() {} const_span(int x_, unsigned len_, const cover_type* covers_) : x(x_), len(len_), covers(covers_) {} }; typedef const const_span* const_iterator; //---------------------------------------------------------------- scanline_single_span(int x, int y, unsigned len, const cover_type* covers) : m_y(y), m_span(x, len, covers) {} //---------------------------------------------------------------- int y() const { return m_y; } unsigned num_spans() const { return 1; } const_iterator begin() const { return &m_span; } private: //---------------------------------------------------------------- int m_y; const_span m_span; }; //-------------------------------------------------------------------- renderer_raster_htext(ren_type& ren, glyph_gen_type& glyph) : m_ren(&ren), m_glyph(&glyph) { } //-------------------------------------------------------------------- template void render_text(double x, double y, const CharT* str, bool flip=false) { glyph_rect r; while(*str) { m_glyph->prepare(&r, x, y, *str, flip); if(r.x2 >= r.x1) { m_ren->prepare(r.x2 - r.x1 + 1); int i; if(flip) { for(i = r.y1; i <= r.y2; i++) { m_ren->render( scanline_single_span(r.x1, i, (r.x2 - r.x1 + 1), m_glyph->span(r.y2 - i))); } } else { for(i = r.y1; i <= r.y2; i++) { m_ren->render( scanline_single_span(r.x1, i, (r.x2 - r.x1 + 1), m_glyph->span(i - r.y1))); } } } x += r.dx; y += r.dy; ++str; } } private: ren_type* m_ren; glyph_gen_type* m_glyph; }; } #endif aggdraw-1.3.14/agg2/include/agg_renderer_scanline.h000066400000000000000000000224501417726601400221430ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_RENDERER_SCANLINE_INCLUDED #define AGG_RENDERER_SCANLINE_INCLUDED #include "agg_basics.h" #include "agg_renderer_base.h" #include "agg_render_scanlines.h" namespace agg { //====================================================renderer_scanline_aa template class renderer_scanline_aa { public: typedef BaseRenderer base_ren_type; //-------------------------------------------------------------------- renderer_scanline_aa(base_ren_type& ren, SpanGenerator& span_gen) : m_ren(&ren), m_span_gen(&span_gen) { } //-------------------------------------------------------------------- void prepare(unsigned max_span_len) { m_span_gen->prepare(max_span_len); } //-------------------------------------------------------------------- template void render(const Scanline& sl) { int y = sl.y(); m_ren->first_clip_box(); do { int xmin = m_ren->xmin(); int xmax = m_ren->xmax(); if(y >= m_ren->ymin() && y <= m_ren->ymax()) { unsigned num_spans = sl.num_spans(); typename Scanline::const_iterator span = sl.begin(); do { int x = span->x; int len = span->len; bool solid = false; const typename Scanline::cover_type* covers = span->covers; if(len < 0) { solid = true; len = -len; } if(x < xmin) { len -= xmin - x; covers += xmin - x; x = xmin; } if(len > 0) { if(x + len > xmax) { len = xmax - x + 1; } if(len > 0) { m_ren->blend_color_hspan_no_clip( x, y, len, m_span_gen->generate(x, y, len), solid ? 0 : covers, *covers); } } ++span; } while(--num_spans); } } while(m_ren->next_clip_box()); } private: base_ren_type* m_ren; SpanGenerator* m_span_gen; }; //==============================================renderer_scanline_aa_solid template class renderer_scanline_aa_solid { public: typedef BaseRenderer base_ren_type; typedef typename base_ren_type::color_type color_type; //-------------------------------------------------------------------- renderer_scanline_aa_solid(base_ren_type& ren) : m_ren(&ren) { } //-------------------------------------------------------------------- void color(const color_type& c) { m_color = c; } const color_type& color() const { return m_color; } //-------------------------------------------------------------------- void prepare(unsigned) {} //-------------------------------------------------------------------- template void render(const Scanline& sl) { int y = sl.y(); unsigned num_spans = sl.num_spans(); typename Scanline::const_iterator span = sl.begin(); do { int x = span->x; if(span->len > 0) { m_ren->blend_solid_hspan(x, y, (unsigned)span->len, m_color, span->covers); } else { m_ren->blend_hline(x, y, (unsigned)(x - span->len - 1), m_color, *(span->covers)); } ++span; } while(--num_spans); } private: base_ren_type* m_ren; color_type m_color; }; //===================================================renderer_scanline_bin template class renderer_scanline_bin { public: typedef BaseRenderer base_ren_type; //-------------------------------------------------------------------- renderer_scanline_bin(base_ren_type& ren, SpanGenerator& span_gen) : m_ren(&ren), m_span_gen(&span_gen) { } //-------------------------------------------------------------------- void prepare(unsigned max_span_len) { m_span_gen->prepare(max_span_len); } //-------------------------------------------------------------------- template void render(const Scanline& sl) { int y = sl.y(); m_ren->first_clip_box(); do { int xmin = m_ren->xmin(); int xmax = m_ren->xmax(); if(y >= m_ren->ymin() && y <= m_ren->ymax()) { unsigned num_spans = sl.num_spans(); typename Scanline::const_iterator span = sl.begin(); do { int x = span->x; int len = span->len; if(len < 0) len = -len; if(x < xmin) { len -= xmin - x; x = xmin; } if(len > 0) { if(x + len > xmax) { len = xmax - x + 1; } if(len > 0) { m_ren->blend_color_hspan_no_clip( x, y, len, m_span_gen->generate(x, y, len), 0); } } ++span; } while(--num_spans); } } while(m_ren->next_clip_box()); } private: base_ren_type* m_ren; SpanGenerator* m_span_gen; }; //=============================================renderer_scanline_bin_solid template class renderer_scanline_bin_solid { public: typedef BaseRenderer base_ren_type; typedef typename base_ren_type::color_type color_type; //-------------------------------------------------------------------- renderer_scanline_bin_solid(base_ren_type& ren) : m_ren(&ren) { } //-------------------------------------------------------------------- void color(const color_type& c) { m_color = c; } const color_type& color() const { return m_color; } //-------------------------------------------------------------------- void prepare(unsigned) {} //-------------------------------------------------------------------- template void render(const Scanline& sl) { unsigned num_spans = sl.num_spans(); typename Scanline::const_iterator span = sl.begin(); do { m_ren->blend_hline(span->x, sl.y(), span->x - 1 + ((span->len < 0) ? -span->len : span->len), m_color, cover_full); ++span; } while(--num_spans); } private: base_ren_type* m_ren; color_type m_color; }; } #endif aggdraw-1.3.14/agg2/include/agg_rendering_buffer.h000066400000000000000000000111771417726601400217730ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // class rendering_buffer // //---------------------------------------------------------------------------- #ifndef AGG_RENDERING_BUFFER_INCLUDED #define AGG_RENDERING_BUFFER_INCLUDED #include "agg_basics.h" namespace agg { //==========================================================row_ptr_cache template class row_ptr_cache { public: //------------------------------------------------------------------- ~row_ptr_cache() { delete [] m_rows; } //------------------------------------------------------------------- row_ptr_cache() : m_buf(0), m_rows(0), m_width(0), m_height(0), m_stride(0), m_max_height(0) { } //-------------------------------------------------------------------- row_ptr_cache(T* buf, unsigned width, unsigned height, int stride) : m_buf(0), m_rows(0), m_width(0), m_height(0), m_stride(0), m_max_height(0) { attach(buf, width, height, stride); } //-------------------------------------------------------------------- void attach(T* buf, unsigned width, unsigned height, int stride) { m_buf = buf; m_width = width; m_height = height; m_stride = stride; if(height > m_max_height) { delete [] m_rows; m_rows = new T* [m_max_height = height]; } T* row_ptr = m_buf; if(stride < 0) { row_ptr = m_buf - int(height - 1) * stride; } T** rows = m_rows; while(height--) { *rows++ = row_ptr; row_ptr += stride; } } //-------------------------------------------------------------------- const T* buf() const { return m_buf; } unsigned width() const { return m_width; } unsigned height() const { return m_height; } int stride() const { return m_stride; } unsigned stride_abs() const { return (m_stride < 0) ? unsigned(-m_stride) : unsigned(m_stride); } //-------------------------------------------------------------------- T* row(unsigned y) { return m_rows[y]; } const T* row(unsigned y) const { return m_rows[y]; } T const* const* rows() const { return m_rows; } //-------------------------------------------------------------------- void copy_from(const row_ptr_cache& mtx) { unsigned h = height(); if(mtx.height() < h) h = mtx.height(); unsigned l = stride_abs(); if(mtx.stride_abs() < l) l = mtx.stride_abs(); l *= sizeof(T); unsigned y; for (y = 0; y < h; y++) { memcpy(row(y), mtx.row(y), l); } } private: //-------------------------------------------------------------------- // Prohibit copying row_ptr_cache(const row_ptr_cache&); const row_ptr_cache& operator = (const row_ptr_cache&); private: //-------------------------------------------------------------------- T* m_buf; // Pointer to renrdering buffer T** m_rows; // Pointers to each row of the buffer unsigned m_width; // Width in pixels unsigned m_height; // Height in pixels int m_stride; // Number of bytes per row. Can be < 0 unsigned m_max_height; // The maximal height (currently allocated) }; //========================================================rendering_buffer typedef row_ptr_cache rendering_buffer; } #endif aggdraw-1.3.14/agg2/include/agg_rounded_rect.h000066400000000000000000000047101417726601400211350ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Rounded rectangle vertex generator // //---------------------------------------------------------------------------- #ifndef AGG_ROUNDED_RECT_INCLUDED #define AGG_ROUNDED_RECT_INCLUDED #include "agg_basics.h" #include "agg_arc.h" #include "agg_vertex_iterator.h" namespace agg { //------------------------------------------------------------rounded_rect // // See Implemantation agg_rounded_rect.cpp // class rounded_rect { public: rounded_rect() {} rounded_rect(double x1, double y1, double x2, double y2, double r); void rect(double x1, double y1, double x2, double y2); void radius(double r); void radius(double rx, double ry); void radius(double rx_bottom, double ry_bottom, double rx_top, double ry_top); void radius(double rx1, double ry1, double rx2, double ry2, double rx3, double ry3, double rx4, double ry4); void normalize_radius(); void approximation_scale(double s) { m_arc.approximation_scale(s); } double approximation_scale() const { return m_arc.approximation_scale(); } void rewind(unsigned); unsigned vertex(double* x, double* y); typedef rounded_rect source_type; typedef vertex_iterator iterator; iterator begin(unsigned id) { return iterator(*this, id); } iterator end() { return iterator(path_cmd_stop); } private: double m_x1; double m_y1; double m_x2; double m_y2; double m_rx1; double m_ry1; double m_rx2; double m_ry2; double m_rx3; double m_ry3; double m_rx4; double m_ry4; unsigned m_status; arc m_arc; }; } #endif aggdraw-1.3.14/agg2/include/agg_scanline_bin.h000066400000000000000000000113461417726601400211070ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Class scanline_bin - binary scanline. // //---------------------------------------------------------------------------- #ifndef AGG_SCANLINE_BIN_INCLUDED #define AGG_SCANLINE_BIN_INCLUDED #include "agg_basics.h" namespace agg { //=============================================================scanline_bin // // This is binary scaline container which supports the interface // used in the rasterizer::render(). See description of agg_scanline_u8 // for details. // // Rendering: //------------------------------------------------------------------------- // // int y = sl.y(); // // ************************************ // ...Perform vertical clipping here... // ************************************ // // unsigned num_spans = sl.num_spans(); // const agg::scanline_bin::span* cur_span = sl.spans(); // // do // { // x = cur_span->x; // len = cur_span->len; // // ************************************** // ...Perform horizontal clipping here... // ************************************** // // hor_line(x, y, len) // ++cur_span; // } // while(--num_spans); // //------------------------------------------------------------------------ class scanline_bin { public: struct span { int16 x; int16 len; }; typedef const span* const_iterator; ~scanline_bin() { delete [] m_spans; } scanline_bin() : m_max_len(0), m_last_x(0x7FFF), m_spans(0), m_cur_span(0) { } void reset(int min_x, int max_x); void add_cell(int x, unsigned); void add_cells(int x, unsigned len, const void*); void add_span(int x, unsigned len, unsigned); void finalize(int y) { m_y = y; } void reset_spans(); int y() const { return m_y; } unsigned num_spans() const { return unsigned(m_cur_span - m_spans); } const_iterator begin() const { return m_spans + 1; } private: scanline_bin(const scanline_bin&); const scanline_bin operator = (const scanline_bin&); unsigned m_max_len; int m_last_x; int m_y; span* m_spans; span* m_cur_span; }; //------------------------------------------------------------------------ inline void scanline_bin::reset(int min_x, int max_x) { unsigned max_len = max_x - min_x + 3; if(max_len > m_max_len) { delete [] m_spans; m_spans = new span [max_len]; m_max_len = max_len; } m_last_x = 0x7FFF; m_cur_span = m_spans; } //------------------------------------------------------------------------ inline void scanline_bin::reset_spans() { m_last_x = 0x7FFF; m_cur_span = m_spans; } //------------------------------------------------------------------------ inline void scanline_bin::add_cell(int x, unsigned) { if(x == m_last_x+1) { m_cur_span->len++; } else { ++m_cur_span; m_cur_span->x = (int16)x; m_cur_span->len = 1; } m_last_x = x; } //------------------------------------------------------------------------ inline void scanline_bin::add_span(int x, unsigned len, unsigned) { if(x == m_last_x+1) { m_cur_span->len = (int16)(m_cur_span->len + len); } else { ++m_cur_span; m_cur_span->x = (int16)x; m_cur_span->len = (int16)len; } m_last_x = x + len - 1; } //------------------------------------------------------------------------ inline void scanline_bin::add_cells(int x, unsigned len, const void*) { add_span(x, len, 0); } } #endif aggdraw-1.3.14/agg2/include/agg_scanline_boolean_algebra.h000066400000000000000000001463001417726601400234320ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_SCANLINE_BOOLEAN_ALGEBRA_INCLUDED #define AGG_SCANLINE_BOOLEAN_ALGEBRA_INCLUDED #include #include #include "agg_basics.h" namespace agg { //-----------------------------------------------sbool_combine_spans_bin // Functor. // Combine two binary encoded spans, i.e., when we don't have any // anti-aliasing information, but only X and Length. The function // is compatible with any type of scanlines. //---------------- template struct sbool_combine_spans_bin { void operator () (const typename Scanline1::const_iterator&, const typename Scanline2::const_iterator&, int x, unsigned len, Scanline& sl) const { sl.add_span(x, len, cover_full); } }; //---------------------------------------------sbool_combine_spans_empty // Functor. // Combine two spans as empty ones. The functor does nothing // and is used to XOR binary spans. //---------------- template struct sbool_combine_spans_empty { void operator () (const typename Scanline1::const_iterator&, const typename Scanline2::const_iterator&, int, unsigned, Scanline&) const {} }; //--------------------------------------------------sbool_add_span_empty // Functor. // Add nothing. Used in conbine_shapes_sub //---------------- template struct sbool_add_span_empty { void operator () (const typename Scanline1::const_iterator&, int, unsigned, Scanline&) const {} }; //----------------------------------------------------sbool_add_span_bin // Functor. // Add a binary span //---------------- template struct sbool_add_span_bin { void operator () (const typename Scanline1::const_iterator&, int x, unsigned len, Scanline& sl) const { sl.add_span(x, len, cover_full); } }; //-----------------------------------------------------sbool_add_span_aa // Functor. // Add an anti-aliased span // anti-aliasing information, but only X and Length. The function // is compatible with any type of scanlines. //---------------- template struct sbool_add_span_aa { void operator () (const typename Scanline1::const_iterator& span, int x, unsigned len, Scanline& sl) const { if(span->len < 0) { sl.add_span(x, len, *span->covers); } else if(span->len > 0) { const typename Scanline1::cover_type* covers = span->covers; if(span->x < x) covers += x - span->x; sl.add_cells(x, len, covers); } } }; //----------------------------------------------sbool_intersect_spans_aa // Functor. // Intersect two spans preserving the anti-aliasing information. // The result is added to the "sl" scanline. //------------------ template struct sbool_intersect_spans_aa { enum { cover_shift = CoverShift, cover_size = 1 << cover_shift, cover_mask = cover_size - 1, cover_full = cover_mask }; void operator () (const typename Scanline1::const_iterator& span1, const typename Scanline2::const_iterator& span2, int x, unsigned len, Scanline& sl) const { unsigned cover; const typename Scanline1::cover_type* covers1; const typename Scanline2::cover_type* covers2; // Calculate the operation code and choose the // proper combination algorithm. // 0 = Both spans are of AA type // 1 = span1 is solid, span2 is AA // 2 = span1 is AA, span2 is solid // 3 = Both spans are of solid type //----------------- switch((span1->len < 0) | ((span2->len < 0) << 1)) { case 0: // Both are AA spans covers1 = span1->covers; covers2 = span2->covers; if(span1->x < x) covers1 += x - span1->x; if(span2->x < x) covers2 += x - span2->x; do { cover = *covers1++ * *covers2++; sl.add_cell(x++, (cover == cover_full * cover_full) ? cover_full : (cover >> cover_shift)); } while(--len); break; case 1: // span1 is solid, span2 is AA covers2 = span2->covers; if(span2->x < x) covers2 += x - span2->x; if(*(span1->covers) == cover_full) { sl.add_cells(x, len, covers2); } else { do { cover = *(span1->covers) * *covers2++; sl.add_cell(x++, (cover == cover_full * cover_full) ? cover_full : (cover >> cover_shift)); } while(--len); } break; case 2: // span1 is AA, span2 is solid covers1 = span1->covers; if(span1->x < x) covers1 += x - span1->x; if(*(span2->covers) == cover_full) { sl.add_cells(x, len, covers1); } else { do { cover = *covers1++ * *(span2->covers); sl.add_cell(x++, (cover == cover_full * cover_full) ? cover_full : (cover >> cover_shift)); } while(--len); } break; case 3: // Both are solid spans cover = *(span1->covers) * *(span2->covers); sl.add_span(x, len, (cover == cover_full * cover_full) ? cover_full : (cover >> cover_shift)); break; } } }; //--------------------------------------------------sbool_unite_spans_aa // Functor. // Unite two spans preserving the anti-aliasing information. // The result is added to the "sl" scanline. //------------------ template struct sbool_unite_spans_aa { enum { cover_shift = CoverShift, cover_size = 1 << cover_shift, cover_mask = cover_size - 1, cover_full = cover_mask }; void operator () (const typename Scanline1::const_iterator& span1, const typename Scanline2::const_iterator& span2, int x, unsigned len, Scanline& sl) const { unsigned cover; const typename Scanline1::cover_type* covers1; const typename Scanline2::cover_type* covers2; // Calculate the operation code and choose the // proper combination algorithm. // 0 = Both spans are of AA type // 1 = span1 is solid, span2 is AA // 2 = span1 is AA, span2 is solid // 3 = Both spans are of solid type //----------------- switch((span1->len < 0) | ((span2->len < 0) << 1)) { case 0: // Both are AA spans covers1 = span1->covers; covers2 = span2->covers; if(span1->x < x) covers1 += x - span1->x; if(span2->x < x) covers2 += x - span2->x; do { cover = cover_mask * cover_mask - (cover_mask - *covers1++) * (cover_mask - *covers2++); sl.add_cell(x++, (cover == cover_full * cover_full) ? cover_full : (cover >> cover_shift)); } while(--len); break; case 1: // span1 is solid, span2 is AA covers2 = span2->covers; if(span2->x < x) covers2 += x - span2->x; if(*(span1->covers) == cover_full) { sl.add_span(x, len, cover_full); } else { do { cover = cover_mask * cover_mask - (cover_mask - *(span1->covers)) * (cover_mask - *covers2++); sl.add_cell(x++, (cover == cover_full * cover_full) ? cover_full : (cover >> cover_shift)); } while(--len); } break; case 2: // span1 is AA, span2 is solid covers1 = span1->covers; if(span1->x < x) covers1 += x - span1->x; if(*(span2->covers) == cover_full) { sl.add_span(x, len, cover_full); } else { do { cover = cover_mask * cover_mask - (cover_mask - *covers1++) * (cover_mask - *(span2->covers)); sl.add_cell(x++, (cover == cover_full * cover_full) ? cover_full : (cover >> cover_shift)); } while(--len); } break; case 3: // Both are solid spans cover = cover_mask * cover_mask - (cover_mask - *(span1->covers)) * (cover_mask - *(span2->covers)); sl.add_span(x, len, (cover == cover_full * cover_full) ? cover_full : (cover >> cover_shift)); break; } } }; //---------------------------------------------sbool_xor_formula_saddle template struct sbool_xor_formula_saddle { enum { cover_shift = CoverShift, cover_size = 1 << cover_shift, cover_mask = cover_size - 1 }; static unsigned calculate(unsigned a, unsigned b) { unsigned k = a * b; if(k == cover_mask * cover_mask) return 0; a = (cover_mask * cover_mask - (a << cover_shift) + k) >> cover_shift; b = (cover_mask * cover_mask - (b << cover_shift) + k) >> cover_shift; return cover_mask - ((a * b) >> cover_shift); } }; //--------------------------------------------sbool_xor_formula_linear template struct sbool_xor_formula_linear { enum { cover_shift = CoverShift, cover_size = 1 << cover_shift, cover_mask = cover_size - 1 }; static unsigned calculate(unsigned a, unsigned b) { unsigned cover = a + b; if(cover > cover_mask) cover = cover_mask + cover_mask - cover; return cover; } }; //----------------------------------------------------sbool_xor_spans_aa // Functor. // XOR two spans preserving the anti-aliasing information. // The result is added to the "sl" scanline. //------------------ template struct sbool_xor_spans_aa { enum { cover_shift = CoverShift, cover_size = 1 << cover_shift, cover_mask = cover_size - 1, cover_full = cover_mask }; void operator () (const typename Scanline1::const_iterator& span1, const typename Scanline2::const_iterator& span2, int x, unsigned len, Scanline& sl) const { unsigned cover; const typename Scanline1::cover_type* covers1; const typename Scanline2::cover_type* covers2; // Calculate the operation code and choose the // proper combination algorithm. // 0 = Both spans are of AA type // 1 = span1 is solid, span2 is AA // 2 = span1 is AA, span2 is solid // 3 = Both spans are of solid type //----------------- switch((span1->len < 0) | ((span2->len < 0) << 1)) { case 0: // Both are AA spans covers1 = span1->covers; covers2 = span2->covers; if(span1->x < x) covers1 += x - span1->x; if(span2->x < x) covers2 += x - span2->x; do { cover = XorFormula::calculate(*covers1++, *covers2++); if(cover) sl.add_cell(x, cover); ++x; } while(--len); break; case 1: // span1 is solid, span2 is AA covers2 = span2->covers; if(span2->x < x) covers2 += x - span2->x; do { cover = XorFormula::calculate(*(span1->covers), *covers2++); if(cover) sl.add_cell(x, cover); ++x; } while(--len); break; case 2: // span1 is AA, span2 is solid covers1 = span1->covers; if(span1->x < x) covers1 += x - span1->x; do { cover = XorFormula::calculate(*covers1++, *(span2->covers)); if(cover) sl.add_cell(x, cover); ++x; } while(--len); break; case 3: // Both are solid spans cover = XorFormula::calculate(*(span1->covers), *(span2->covers)); if(cover) sl.add_span(x, len, cover); break; } } }; //-----------------------------------------------sbool_subtract_spans_aa // Functor. // Unite two spans preserving the anti-aliasing information. // The result is added to the "sl" scanline. //------------------ template struct sbool_subtract_spans_aa { enum { cover_shift = CoverShift, cover_size = 1 << cover_shift, cover_mask = cover_size - 1, cover_full = cover_mask }; void operator () (const typename Scanline1::const_iterator& span1, const typename Scanline2::const_iterator& span2, int x, unsigned len, Scanline& sl) const { unsigned cover; const typename Scanline1::cover_type* covers1; const typename Scanline2::cover_type* covers2; // Calculate the operation code and choose the // proper combination algorithm. // 0 = Both spans are of AA type // 1 = span1 is solid, span2 is AA // 2 = span1 is AA, span2 is solid // 3 = Both spans are of solid type //----------------- switch((span1->len < 0) | ((span2->len < 0) << 1)) { case 0: // Both are AA spans covers1 = span1->covers; covers2 = span2->covers; if(span1->x < x) covers1 += x - span1->x; if(span2->x < x) covers2 += x - span2->x; do { cover = *covers1++ * (cover_mask - *covers2++); if(cover) { sl.add_cell(x, (cover == cover_full * cover_full) ? cover_full : (cover >> cover_shift)); } ++x; } while(--len); break; case 1: // span1 is solid, span2 is AA covers2 = span2->covers; if(span2->x < x) covers2 += x - span2->x; do { cover = *(span1->covers) * (cover_mask - *covers2++); if(cover) { sl.add_cell(x, (cover == cover_full * cover_full) ? cover_full : (cover >> cover_shift)); } ++x; } while(--len); break; case 2: // span1 is AA, span2 is solid covers1 = span1->covers; if(span1->x < x) covers1 += x - span1->x; if(*(span2->covers) != cover_full) { do { cover = *covers1++ * (cover_mask - *(span2->covers)); if(cover) { sl.add_cell(x, (cover == cover_full * cover_full) ? cover_full : (cover >> cover_shift)); } ++x; } while(--len); } break; case 3: // Both are solid spans cover = *(span1->covers) * (cover_mask - *(span2->covers)); if(cover) { sl.add_span(x, len, (cover == cover_full * cover_full) ? cover_full : (cover >> cover_shift)); } break; } } }; //--------------------------------------------sbool_add_spans_and_render template void sbool_add_spans_and_render(const Scanline1& sl1, Scanline& sl, Renderer& ren, AddSpanFunctor add_span) { sl.reset_spans(); typename Scanline::const_iterator span = sl1.begin(); unsigned num_spans = sl1.num_spans(); do { add_span(span, span->x, abs((int)span->len), sl); ++span; } while(--num_spans); sl.finalize(sl1.y()); ren.render(sl); } //---------------------------------------------sbool_intersect_scanlines // Intersect two scanlines, "sl1" and "sl2" and generate a new "sl" one. // The combine_spans functor can be of type sbool_combine_spans_bin or // sbool_intersect_spans_aa. First is a general functor to combine // two spans without Anti-Aliasing, the second preserves the AA // information, but works slower // template void sbool_intersect_scanlines(const Scanline1& sl1, const Scanline2& sl2, Scanline& sl, CombineSpansFunctor combine_spans) { sl.reset_spans(); unsigned num1 = sl1.num_spans(); if(num1 == 0) return; unsigned num2 = sl2.num_spans(); if(num2 == 0) return; typename Scanline::const_iterator span1 = sl1.begin(); typename Scanline::const_iterator span2 = sl2.begin(); while(num1 && num2) { int xb1 = span1->x; int xb2 = span2->x; int xe1 = xb1 + abs((int)span1->len) - 1; int xe2 = xb2 + abs((int)span2->len) - 1; // Determine what spans we should advance in the next step // The span with the least ending X should be advanced // advance_both is just an optimization when we ending // coordinates are the same and we can advance both //-------------- bool advance_span1 = xe1 < xe2; bool advance_both = xe1 == xe2; // Find the intersection of the spans // and check if they intersect //-------------- if(xb1 < xb2) xb1 = xb2; if(xe1 > xe2) xe1 = xe2; if(xb1 <= xe1) { combine_spans(span1, span2, xb1, xe1 - xb1 + 1, sl); } // Advance the spans //-------------- if(advance_both) { --num1; --num2; ++span1; ++span2; } else { if(advance_span1) { --num1; ++span1; } else { --num2; ++span2; } } } } //------------------------------------------------sbool_intersect_shapes // Intersect the scanline shapes. Here the "Scanline Generator" // abstraction is used. ScanlineGen1 and ScanlineGen2 are // the generators, and can be of type rasterizer_scanline_aa<>. // There function requires three scanline containers that can be of // different types. // "sl1" and "sl2" are used to retrieve scanlines from the generators, // "sl" is ised as the resulting scanline to render it. // The external "sl1" and "sl2" are used only for the sake of // optimization and reusing of the scanline objects. // the function calls sbool_intersect_scanlines with CombineSpansFunctor // as the last argument. See sbool_intersect_scanlines for details. //---------- template void sbool_intersect_shapes(ScanlineGen1& sg1, ScanlineGen2& sg2, Scanline1& sl1, Scanline2& sl2, Scanline& sl, Renderer& ren, CombineSpansFunctor combine_spans) { // Prepare the scanline generators. // If anyone of them doesn't contain // any scanlines, then return. //----------------- if(!sg1.rewind_scanlines()) return; if(!sg2.rewind_scanlines()) return; // Get the bounding boxes //---------------- rect r1(sg1.min_x(), sg1.min_y(), sg1.max_x(), sg1.max_y()); rect r2(sg2.min_x(), sg2.min_y(), sg2.max_x(), sg2.max_y()); // Calculate the intersection of the bounding // boxes and return if they don't intersect. //----------------- rect ir = intersect_rectangles(r1, r2); if(!ir.is_valid()) return; // Reset the scanlines and get two first ones //----------------- sl.reset(ir.x1, ir.x2); sl1.reset(sg1.min_x(), sg1.max_x()); sl2.reset(sg2.min_x(), sg2.max_x()); if(!sg1.sweep_scanline(sl1)) return; if(!sg2.sweep_scanline(sl2)) return; ren.prepare(unsigned(ir.x2 - ir.x1 + 2)); // The main loop // Here we synchronize the scanlines with // the same Y coordinate, ignoring all other ones. // Only scanlines having the same Y-coordinate // are to be combined. //----------------- for(;;) { while(sl1.y() < sl2.y()) { if(!sg1.sweep_scanline(sl1)) return; } while(sl2.y() < sl1.y()) { if(!sg2.sweep_scanline(sl2)) return; } if(sl1.y() == sl2.y()) { // The Y coordinates are the same. // Combine the scanlines, render if they contain any spans, // and advance both generators to the next scanlines //---------------------- sbool_intersect_scanlines(sl1, sl2, sl, combine_spans); if(sl.num_spans()) { sl.finalize(sl1.y()); ren.render(sl); } if(!sg1.sweep_scanline(sl1)) return; if(!sg2.sweep_scanline(sl2)) return; } } } //-------------------------------------------------sbool_unite_scanlines // Unite two scanlines, "sl1" and "sl2" and generate a new "sl" one. // The combine_spans functor can be of type sbool_combine_spans_bin or // sbool_intersect_spans_aa. First is a general functor to combine // two spans without Anti-Aliasing, the second preserves the AA // information, but works slower // template void sbool_unite_scanlines(const Scanline1& sl1, const Scanline2& sl2, Scanline& sl, AddSpanFunctor1 add_span1, AddSpanFunctor2 add_span2, CombineSpansFunctor combine_spans) { sl.reset_spans(); unsigned num1 = sl1.num_spans(); unsigned num2 = sl2.num_spans(); typename Scanline::const_iterator span1; typename Scanline::const_iterator span2; enum { invalid_b = 0x7FFFFFFF, invalid_e = invalid_b - 1 }; // Initialize the spans as invalid //--------------- int xb1 = invalid_b; int xb2 = invalid_b; int xe1 = invalid_e; int xe2 = invalid_e; // Initialize span1 if there are spans //--------------- if(num1) { span1 = sl1.begin(); xb1 = span1->x; xe1 = xb1 + abs((int)span1->len) - 1; --num1; } // Initialize span2 if there are spans //--------------- if(num2) { span2 = sl2.begin(); xb2 = span2->x; xe2 = xb2 + abs((int)span2->len) - 1; --num2; } for(;;) { // Retrieve a new span1 if it's invalid //---------------- if(num1 && xb1 > xe1) { --num1; ++span1; xb1 = span1->x; xe1 = xb1 + abs((int)span1->len) - 1; } // Retrieve a new span2 if it's invalid //---------------- if(num2 && xb2 > xe2) { --num2; ++span2; xb2 = span2->x; xe2 = xb2 + abs((int)span2->len) - 1; } if(xb1 > xe1 && xb2 > xe2) break; // Calculate the intersection //---------------- int xb = xb1; int xe = xe1; if(xb < xb2) xb = xb2; if(xe > xe2) xe = xe2; int len = xe - xb + 1; // The length of the intersection if(len > 0) { // The spans intersect, // add the beginning of the span //---------------- if(xb1 < xb2) { add_span1(span1, xb1, xb2 - xb1, sl); xb1 = xb2; } else if(xb2 < xb1) { add_span2(span2, xb2, xb1 - xb2, sl); xb2 = xb1; } // Add the combination part of the spans //---------------- combine_spans(span1, span2, xb, len, sl); // Invalidate the fully processed span or both //---------------- if(xe1 < xe2) { // Invalidate span1 and eat // the processed part of span2 //-------------- xb1 = invalid_b; xe1 = invalid_e; xb2 += len; } else if(xe2 < xe1) { // Invalidate span2 and eat // the processed part of span1 //-------------- xb2 = invalid_b; xe2 = invalid_e; xb1 += len; } else { xb1 = invalid_b; // Invalidate both xb2 = invalid_b; xe1 = invalid_e; xe2 = invalid_e; } } else { // The spans do not intersect //-------------- if(xb1 < xb2) { // Advance span1 //--------------- if(xb1 <= xe1) { add_span1(span1, xb1, xe1 - xb1 + 1, sl); } xb1 = invalid_b; // Invalidate xe1 = invalid_e; } else { // Advance span2 //--------------- if(xb2 <= xe2) { add_span2(span2, xb2, xe2 - xb2 + 1, sl); } xb2 = invalid_b; // Invalidate xe2 = invalid_e; } } } } //----------------------------------------------------sbool_unite_shapes // Unite the scanline shapes. Here the "Scanline Generator" // abstraction is used. ScanlineGen1 and ScanlineGen2 are // the generators, and can be of type rasterizer_scanline_aa<>. // There function requires three scanline containers that can be // of different type. // "sl1" and "sl2" are used to retrieve scanlines from the generators, // "sl" is ised as the resulting scanline to render it. // The external "sl1" and "sl2" are used only for the sake of // optimization and reusing of the scanline objects. // the function calls sbool_unite_scanlines with CombineSpansFunctor // as the last argument. See sbool_unite_scanlines for details. //---------- template void sbool_unite_shapes(ScanlineGen1& sg1, ScanlineGen2& sg2, Scanline1& sl1, Scanline2& sl2, Scanline& sl, Renderer& ren, AddSpanFunctor1 add_span1, AddSpanFunctor2 add_span2, CombineSpansFunctor combine_spans) { // Prepare the scanline generators. // If anyone of them doesn't contain // any scanlines, then return. //----------------- bool flag1 = sg1.rewind_scanlines(); bool flag2 = sg2.rewind_scanlines(); if(!flag1 && !flag2) return; // Get the bounding boxes //---------------- rect r1(sg1.min_x(), sg1.min_y(), sg1.max_x(), sg1.max_y()); rect r2(sg2.min_x(), sg2.min_y(), sg2.max_x(), sg2.max_y()); // Calculate the union of the bounding boxes //----------------- rect ur = unite_rectangles(r1, r2); if(!ur.is_valid()) return; ren.prepare(unsigned(ur.x2 - ur.x2 + 2)); // Reset the scanlines and get two first ones //----------------- sl.reset(ur.x1, ur.x2); if(flag1) { sl1.reset(sg1.min_x(), sg1.max_x()); flag1 = sg1.sweep_scanline(sl1); } if(flag2) { sl2.reset(sg2.min_x(), sg2.max_x()); flag2 = sg2.sweep_scanline(sl2); } // The main loop // Here we synchronize the scanlines with // the same Y coordinate. //----------------- while(flag1 || flag2) { if(flag1 && flag2) { if(sl1.y() == sl2.y()) { // The Y coordinates are the same. // Combine the scanlines, render if they contain any spans, // and advance both generators to the next scanlines //---------------------- sbool_unite_scanlines(sl1, sl2, sl, add_span1, add_span2, combine_spans); if(sl.num_spans()) { sl.finalize(sl1.y()); ren.render(sl); } flag1 = sg1.sweep_scanline(sl1); flag2 = sg2.sweep_scanline(sl2); } else { if(sl1.y() < sl2.y()) { sbool_add_spans_and_render(sl1, sl, ren, add_span1); flag1 = sg1.sweep_scanline(sl1); } else { sbool_add_spans_and_render(sl2, sl, ren, add_span2); flag2 = sg2.sweep_scanline(sl2); } } } else { if(flag1) { sbool_add_spans_and_render(sl1, sl, ren, add_span1); flag1 = sg1.sweep_scanline(sl1); } if(flag2) { sbool_add_spans_and_render(sl2, sl, ren, add_span2); flag2 = sg2.sweep_scanline(sl2); } } } } //-------------------------------------------------sbool_subtract_shapes // Subtract the scanline shapes, "sg1-sg2". Here the "Scanline Generator" // abstraction is used. ScanlineGen1 and ScanlineGen2 are // the generators, and can be of type rasterizer_scanline_aa<>. // There function requires three scanline containers that can be of // different types. // "sl1" and "sl2" are used to retrieve scanlines from the generators, // "sl" is ised as the resulting scanline to render it. // The external "sl1" and "sl2" are used only for the sake of // optimization and reusing of the scanline objects. // the function calls sbool_intersect_scanlines with CombineSpansFunctor // as the last argument. See combine_scanlines_sub for details. //---------- template void sbool_subtract_shapes(ScanlineGen1& sg1, ScanlineGen2& sg2, Scanline1& sl1, Scanline2& sl2, Scanline& sl, Renderer& ren, AddSpanFunctor1 add_span1, CombineSpansFunctor combine_spans) { // Prepare the scanline generators. // Here "sg1" is master, "sg2" is slave. //----------------- if(!sg1.rewind_scanlines()) return; bool flag2 = sg2.rewind_scanlines(); // Get the bounding box //---------------- rect r1(sg1.min_x(), sg1.min_y(), sg1.max_x(), sg1.max_y()); // Reset the scanlines and get two first ones //----------------- sl.reset(sg1.min_x(), sg1.max_x()); sl1.reset(sg1.min_x(), sg1.max_x()); sl2.reset(sg2.min_x(), sg2.max_x()); if(!sg1.sweep_scanline(sl1)) return; if(flag2) flag2 = sg2.sweep_scanline(sl2); ren.prepare(unsigned(sg1.max_x() - sg1.min_x() + 2)); // A fake span2 processor sbool_add_span_empty add_span2; // The main loop // Here we synchronize the scanlines with // the same Y coordinate, ignoring all other ones. // Only scanlines having the same Y-coordinate // are to be combined. //----------------- bool flag1 = true; do { // Synchronize "slave" with "master" //----------------- while(flag2 && sl2.y() < sl1.y()) { flag2 = sg2.sweep_scanline(sl2); } if(flag2 && sl2.y() == sl1.y()) { // The Y coordinates are the same. // Combine the scanlines and render if they contain any spans. //---------------------- sbool_unite_scanlines(sl1, sl2, sl, add_span1, add_span2, combine_spans); if(sl.num_spans()) { sl.finalize(sl1.y()); ren.render(sl); } } else { sbool_add_spans_and_render(sl1, sl, ren, add_span1); } // Advance the "master" flag1 = sg1.sweep_scanline(sl1); } while(flag1); } //---------------------------------------------sbool_intersect_shapes_aa // Intersect two anti-aliased scanline shapes. // Here the "Scanline Generator" abstraction is used. // ScanlineGen1 and ScanlineGen2 are the generators, and can be of // type rasterizer_scanline_aa<>. There function requires three // scanline containers that can be of different types. // "sl1" and "sl2" are used to retrieve scanlines from the generators, // "sl" is ised as the resulting scanline to render it. // The external "sl1" and "sl2" are used only for the sake of // optimization and reusing of the scanline objects. //---------- template void sbool_intersect_shapes_aa(ScanlineGen1& sg1, ScanlineGen2& sg2, Scanline1& sl1, Scanline2& sl2, Scanline& sl, Renderer& ren) { sbool_intersect_spans_aa combine_functor; sbool_intersect_shapes(sg1, sg2, sl1, sl2, sl, ren, combine_functor); } //--------------------------------------------sbool_intersect_shapes_bin // Intersect two binary scanline shapes (without anti-aliasing). // See intersect_shapes_aa for more comments //---------- template void sbool_intersect_shapes_bin(ScanlineGen1& sg1, ScanlineGen2& sg2, Scanline1& sl1, Scanline2& sl2, Scanline& sl, Renderer& ren) { sbool_combine_spans_bin combine_functor; sbool_intersect_shapes(sg1, sg2, sl1, sl2, sl, ren, combine_functor); } //-------------------------------------------------sbool_unite_shapes_aa // Unite two anti-aliased scanline shapes // See intersect_shapes_aa for more comments //---------- template void sbool_unite_shapes_aa(ScanlineGen1& sg1, ScanlineGen2& sg2, Scanline1& sl1, Scanline2& sl2, Scanline& sl, Renderer& ren) { sbool_add_span_aa add_functor1; sbool_add_span_aa add_functor2; sbool_unite_spans_aa combine_functor; sbool_unite_shapes(sg1, sg2, sl1, sl2, sl, ren, add_functor1, add_functor2, combine_functor); } //------------------------------------------------sbool_unite_shapes_bin // Unite two binary scanline shapes (without anti-aliasing). // See intersect_shapes_aa for more comments //---------- template void sbool_unite_shapes_bin(ScanlineGen1& sg1, ScanlineGen2& sg2, Scanline1& sl1, Scanline2& sl2, Scanline& sl, Renderer& ren) { sbool_add_span_bin add_functor1; sbool_add_span_bin add_functor2; sbool_combine_spans_bin combine_functor; sbool_unite_shapes(sg1, sg2, sl1, sl2, sl, ren, add_functor1, add_functor2, combine_functor); } //---------------------------------------------------sbool_xor_shapes_aa // Apply eXclusive OR to two anti-aliased scanline shapes. There's // a modified "Linear" XOR used instead of classical "Saddle" one. // The reason is to have the result absolutely conststent with what // the scanline rasterizer produces. // See intersect_shapes_aa for more comments //---------- template void sbool_xor_shapes_aa(ScanlineGen1& sg1, ScanlineGen2& sg2, Scanline1& sl1, Scanline2& sl2, Scanline& sl, Renderer& ren) { sbool_add_span_aa add_functor1; sbool_add_span_aa add_functor2; sbool_xor_spans_aa > combine_functor; sbool_unite_shapes(sg1, sg2, sl1, sl2, sl, ren, add_functor1, add_functor2, combine_functor); } //------------------------------------------sbool_xor_shapes_saddle_aa // Apply eXclusive OR to two anti-aliased scanline shapes. // There's the classical "Saddle" used to calculate the // Anti-Aliasing values, that is: // a XOR b : 1-((1-a+a*b)*(1-b+a*b)) // See intersect_shapes_aa for more comments //---------- template void sbool_xor_shapes_saddle_aa(ScanlineGen1& sg1, ScanlineGen2& sg2, Scanline1& sl1, Scanline2& sl2, Scanline& sl, Renderer& ren) { sbool_add_span_aa add_functor1; sbool_add_span_aa add_functor2; sbool_xor_spans_aa > combine_functor; sbool_unite_shapes(sg1, sg2, sl1, sl2, sl, ren, add_functor1, add_functor2, combine_functor); } //--------------------------------------------------sbool_xor_shapes_bin // Apply eXclusive OR to two binary scanline shapes (without anti-aliasing). // See intersect_shapes_aa for more comments //---------- template void sbool_xor_shapes_bin(ScanlineGen1& sg1, ScanlineGen2& sg2, Scanline1& sl1, Scanline2& sl2, Scanline& sl, Renderer& ren) { sbool_add_span_bin add_functor1; sbool_add_span_bin add_functor2; sbool_combine_spans_empty combine_functor; sbool_unite_shapes(sg1, sg2, sl1, sl2, sl, ren, add_functor1, add_functor2, combine_functor); } //----------------------------------------------sbool_subtract_shapes_aa // Subtract shapes "sg1-sg2" with anti-aliasing // See intersect_shapes_aa for more comments //---------- template void sbool_subtract_shapes_aa(ScanlineGen1& sg1, ScanlineGen2& sg2, Scanline1& sl1, Scanline2& sl2, Scanline& sl, Renderer& ren) { sbool_add_span_aa add_functor; sbool_subtract_spans_aa combine_functor; sbool_subtract_shapes(sg1, sg2, sl1, sl2, sl, ren, add_functor, combine_functor); } //---------------------------------------------sbool_subtract_shapes_bin // Subtract binary shapes "sg1-sg2" without anti-aliasing // See intersect_shapes_aa for more comments //---------- template void sbool_subtract_shapes_bin(ScanlineGen1& sg1, ScanlineGen2& sg2, Scanline1& sl1, Scanline2& sl2, Scanline& sl, Renderer& ren) { sbool_add_span_bin add_functor; sbool_combine_spans_empty combine_functor; sbool_subtract_shapes(sg1, sg2, sl1, sl2, sl, ren, add_functor, combine_functor); } //------------------------------------------------------------sbool_op_e enum sbool_op_e { sbool_or, //----sbool_or sbool_and, //----sbool_and sbool_xor, //----sbool_xor sbool_xor_saddle, //----sbool_xor_saddle sbool_a_minus_b, //----sbool_a_minus_b sbool_b_minus_a //----sbool_b_minus_a }; //----------------------------------------------sbool_combine_shapes_bin template void sbool_combine_shapes_bin(sbool_op_e op, ScanlineGen1& sg1, ScanlineGen2& sg2, Scanline1& sl1, Scanline2& sl2, Scanline& sl, Renderer& ren) { switch(op) { case sbool_or : sbool_unite_shapes_bin (sg1, sg2, sl1, sl2, sl, ren); break; case sbool_and : sbool_intersect_shapes_bin(sg1, sg2, sl1, sl2, sl, ren); break; case sbool_xor : case sbool_xor_saddle: sbool_xor_shapes_bin (sg1, sg2, sl1, sl2, sl, ren); break; case sbool_a_minus_b : sbool_subtract_shapes_bin (sg1, sg2, sl1, sl2, sl, ren); break; case sbool_b_minus_a : sbool_subtract_shapes_bin (sg2, sg1, sl2, sl1, sl, ren); break; } } //-----------------------------------------------sbool_combine_shapes_aa template void sbool_combine_shapes_aa(sbool_op_e op, ScanlineGen1& sg1, ScanlineGen2& sg2, Scanline1& sl1, Scanline2& sl2, Scanline& sl, Renderer& ren) { switch(op) { case sbool_or : sbool_unite_shapes_aa (sg1, sg2, sl1, sl2, sl, ren); break; case sbool_and : sbool_intersect_shapes_aa (sg1, sg2, sl1, sl2, sl, ren); break; case sbool_xor : sbool_xor_shapes_aa (sg1, sg2, sl1, sl2, sl, ren); break; case sbool_xor_saddle: sbool_xor_shapes_saddle_aa(sg1, sg2, sl1, sl2, sl, ren); break; case sbool_a_minus_b : sbool_subtract_shapes_aa (sg1, sg2, sl1, sl2, sl, ren); break; case sbool_b_minus_a : sbool_subtract_shapes_aa (sg2, sg1, sl2, sl1, sl, ren); break; } } } #endif aggdraw-1.3.14/agg2/include/agg_scanline_p.h000066400000000000000000000132401417726601400205710ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Class scanline_p - a general purpose scanline container with packed spans. // //---------------------------------------------------------------------------- #ifndef AGG_SCANLINE_P_INCLUDED #define AGG_SCANLINE_P_INCLUDED #include "agg_basics.h" namespace agg { //==============================================================scanline_p // // This is a general purpose scaline container which supports the interface // used in the rasterizer::render(). See description of agg_scanline_u // for details. // //------------------------------------------------------------------------ template class scanline_p { public: typedef T cover_type; struct span { int16 x; int16 len; // If negative, it's a solid span, covers is valid const T* covers; }; typedef span* iterator; typedef const span* const_iterator; ~scanline_p() { delete [] m_spans; delete [] m_covers; } scanline_p() : m_max_len(0), m_last_x(0x7FFFFFF0), m_covers(0), m_cover_ptr(0), m_spans(0), m_cur_span(0) { } void reset(int min_x, int max_x); void add_cell(int x, unsigned cover); void add_cells(int x, unsigned len, const T* covers); void add_span(int x, unsigned len, unsigned cover); void finalize(int y) { m_y = y; } void reset_spans(); int y() const { return m_y; } unsigned num_spans() const { return unsigned(m_cur_span - m_spans); } const_iterator begin() const { return m_spans + 1; } private: scanline_p(const scanline_p&); const scanline_p& operator = (const scanline_p&); unsigned m_max_len; int m_last_x; int m_y; T* m_covers; T* m_cover_ptr; span* m_spans; span* m_cur_span; }; //------------------------------------------------------------------------ template void scanline_p::reset(int min_x, int max_x) { unsigned max_len = max_x - min_x + 3; if(max_len > m_max_len) { delete [] m_spans; delete [] m_covers; m_covers = new T [max_len]; m_spans = new span [max_len]; m_max_len = max_len; } m_last_x = 0x7FFFFFF0; m_cover_ptr = m_covers; m_cur_span = m_spans; m_cur_span->len = 0; } //------------------------------------------------------------------------ template void scanline_p::reset_spans() { m_last_x = 0x7FFFFFF0; m_cover_ptr = m_covers; m_cur_span = m_spans; m_cur_span->len = 0; } //------------------------------------------------------------------------ template void scanline_p::add_cell(int x, unsigned cover) { *m_cover_ptr = (T)cover; if(x == m_last_x+1 && m_cur_span->len > 0) { m_cur_span->len++; } else { m_cur_span++; m_cur_span->covers = m_cover_ptr; m_cur_span->x = (int16)x; m_cur_span->len = 1; } m_last_x = x; m_cover_ptr++; } //------------------------------------------------------------------------ template void scanline_p::add_cells(int x, unsigned len, const T* covers) { memcpy(m_cover_ptr, covers, len * sizeof(T)); if(x == m_last_x+1 && m_cur_span->len > 0) { m_cur_span->len += (int16)len; } else { m_cur_span++; m_cur_span->covers = m_cover_ptr; m_cur_span->x = (int16)x; m_cur_span->len = (int16)len; } m_cover_ptr += len; m_last_x = x + len - 1; } //------------------------------------------------------------------------ template void scanline_p::add_span(int x, unsigned len, unsigned cover) { if(x == m_last_x+1 && m_cur_span->len < 0 && cover == *m_cur_span->covers) { m_cur_span->len -= (int16)len; } else { *m_cover_ptr = (T)cover; m_cur_span++; m_cur_span->covers = m_cover_ptr++; m_cur_span->x = (int16)x; m_cur_span->len = -((int16)len); } m_last_x = x + len - 1; } //=============================================================scanline_p8 typedef scanline_p scanline_p8; //============================================================scanline_p16 typedef scanline_p scanline_p16; //============================================================scanline_p32 typedef scanline_p scanline_p32; } #endif aggdraw-1.3.14/agg2/include/agg_scanline_storage_aa.h000066400000000000000000000616351417726601400224520ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_SCANLINE_STORAGE_AA_INCLUDED #define AGG_SCANLINE_STORAGE_AA_INCLUDED #include #include #include #include "agg_array.h" #include "agg_render_scanlines.h" namespace agg { //----------------------------------------------scanline_cell_storage template class scanline_cell_storage { struct extra_span { unsigned len; T* ptr; }; public: typedef T value_type; //--------------------------------------------------------------- ~scanline_cell_storage() { remove_all(); } //--------------------------------------------------------------- scanline_cell_storage() : m_cells(128-2), m_extra_storage() {} // Copying //--------------------------------------------------------------- scanline_cell_storage(const scanline_cell_storage& v) : m_cells(v.m_cells), m_extra_storage() { copy_extra_storage(v); } //--------------------------------------------------------------- const scanline_cell_storage& operator = (const scanline_cell_storage& v) { remove_all(); m_cells = v.m_cells; copy_extra_storage(v); return *this; } //--------------------------------------------------------------- void remove_all() { int i; for(i = m_extra_storage.size()-1; i >= 0; --i) { delete [] m_extra_storage[(unsigned)i].ptr; } m_extra_storage.remove_all(); m_cells.remove_all(); } //--------------------------------------------------------------- int add_cells(const T* cells, unsigned num_cells) { int idx = m_cells.allocate_continuous_block(num_cells); if(idx >= 0) { T* ptr = &m_cells[idx]; memcpy(ptr, cells, sizeof(T) * num_cells); return idx; } extra_span s; s.len = num_cells; s.ptr = new T [num_cells]; memcpy(s.ptr, cells, sizeof(T) * num_cells); m_extra_storage.add(s); return -int(m_extra_storage.size()); } //--------------------------------------------------------------- const T* operator [] (int idx) const { if(idx >= 0) { if((unsigned)idx >= m_cells.size()) return 0; return &m_cells[(unsigned)idx]; } unsigned i = unsigned(-idx - 1); if(i >= m_extra_storage.size()) return 0; return m_extra_storage[i].ptr; } //--------------------------------------------------------------- T* operator [] (int idx) { if(idx >= 0) { if((unsigned)idx >= m_cells.size()) return 0; return &m_cells[(unsigned)idx]; } unsigned i = unsigned(-idx - 1); if(i >= m_extra_storage.size()) return 0; return m_extra_storage[i].ptr; } private: void copy_extra_storage(const scanline_cell_storage& v) { unsigned i; for(i = 0; i < v.m_extra_storage.size(); ++i) { const extra_span& src = v.m_extra_storage[i]; extra_span dst; dst.len = src.len; dst.ptr = new T [dst.len]; memcpy(dst.ptr, src.ptr, dst.len * sizeof(T)); m_extra_storage.add(dst); } } pod_deque m_cells; pod_deque m_extra_storage; }; //-----------------------------------------------scanline_storage_aa template class scanline_storage_aa { public: typedef T cover_type; //--------------------------------------------------------------- struct span_data { int16 x; int16 len; // If negative, it's a solid span, covers is valid int covers_id; // The index of the cells in the scanline_cell_storage }; //--------------------------------------------------------------- struct scanline_data { int y; unsigned num_spans; unsigned start_span; }; //--------------------------------------------------------------- class embedded_scanline { public: //----------------------------------------------------------- class const_iterator { public: struct span { int16 x; int16 len; // If negative, it's a solid span, covers is valid const T* covers; }; const_iterator(const embedded_scanline& sl) : m_storage(sl.m_storage), m_span_idx(sl.m_scanline.start_span) { init_span(); } const span& operator*() const { return m_span; } const span* operator->() const { return &m_span; } void operator ++ () { ++m_span_idx; init_span(); } private: void init_span() { const span_data& s = m_storage->span_by_index(m_span_idx); m_span.x = s.x; m_span.len = s.len; m_span.covers = m_storage->covers_by_index(s.covers_id); } const scanline_storage_aa* m_storage; unsigned m_span_idx; span m_span; }; friend class const_iterator; //----------------------------------------------------------- embedded_scanline(const scanline_storage_aa& storage) : m_storage(&storage) { init(0); } //----------------------------------------------------------- void reset(int, int) {} unsigned num_spans() const { return m_scanline.num_spans; } int y() const { return m_scanline.y; } const_iterator begin() const { return const_iterator(*this); } //----------------------------------------------------------- void init(unsigned scanline_idx) { m_scanline_idx = scanline_idx; m_scanline = m_storage->scanline_by_index(m_scanline_idx); } private: const scanline_storage_aa* m_storage; scanline_data m_scanline; unsigned m_scanline_idx; }; //--------------------------------------------------------------- scanline_storage_aa() : m_covers(), m_spans(256-2), // Block increment size m_scanlines(), m_min_x( 0x7FFFFFFF), m_min_y( 0x7FFFFFFF), m_max_x(-0x7FFFFFFF), m_max_y(-0x7FFFFFFF), m_cur_scanline(0) { m_fake_scanline.y = 0; m_fake_scanline.num_spans = 0; m_fake_scanline.start_span = 0; m_fake_span.x = 0; m_fake_span.len = 0; m_fake_span.covers_id = 0; } // Renderer Interface //--------------------------------------------------------------- void prepare(unsigned) { m_covers.remove_all(); m_scanlines.remove_all(); m_spans.remove_all(); m_min_x = 0x7FFFFFFF; m_min_y = 0x7FFFFFFF; m_max_x = -0x7FFFFFFF; m_max_y = -0x7FFFFFFF; m_cur_scanline = 0; } //--------------------------------------------------------------- template void render(const Scanline& sl) { scanline_data sl_this; int y = sl.y(); if(y < m_min_y) m_min_y = y; if(y > m_max_y) m_max_y = y; sl_this.y = y; sl_this.num_spans = sl.num_spans(); sl_this.start_span = m_spans.size(); typename Scanline::const_iterator span_iterator = sl.begin(); unsigned num_spans = sl_this.num_spans; do { span_data sp; sp.x = span_iterator->x; sp.len = span_iterator->len; sp.covers_id = m_covers.add_cells(span_iterator->covers, unsigned(abs(int(sp.len)))); m_spans.add(sp); int x1 = sp.x; int x2 = sp.x + sp.len - 1; if(x1 < m_min_x) m_min_x = x1; if(x2 > m_max_x) m_max_x = x2; ++span_iterator; } while(--num_spans); m_scanlines.add(sl_this); } //--------------------------------------------------------------- // Iterate scanlines interface int min_x() const { return m_min_x; } int min_y() const { return m_min_y; } int max_x() const { return m_max_x; } int max_y() const { return m_max_y; } //--------------------------------------------------------------- bool rewind_scanlines() { m_cur_scanline = 0; return m_scanlines.size() > 0; } //--------------------------------------------------------------- template bool sweep_scanline(Scanline& sl) { sl.reset_spans(); for(;;) { if(m_cur_scanline >= m_scanlines.size()) return false; const scanline_data& sl_this = m_scanlines[m_cur_scanline]; unsigned num_spans = sl_this.num_spans; unsigned span_idx = sl_this.start_span; do { const span_data& sp = m_spans[span_idx++]; const T* covers = covers_by_index(sp.covers_id); if(sp.len < 0) { sl.add_span(sp.x, unsigned(-sp.len), *covers); } else { sl.add_cells(sp.x, sp.len, covers); } } while(--num_spans); ++m_cur_scanline; if(sl.num_spans()) { sl.finalize(sl_this.y); break; } } return true; } //--------------------------------------------------------------- // Specialization for embedded_scanline bool sweep_scanline(embedded_scanline& sl) { do { if(m_cur_scanline >= m_scanlines.size()) return false; sl.init(m_cur_scanline); ++m_cur_scanline; } while(sl.num_spans() == 0); return true; } //--------------------------------------------------------------- unsigned byte_size() const { unsigned i; unsigned size = sizeof(int16) * 4; // min_x, min_y, max_x, max_y for(i = 0; i < m_scanlines.size(); ++i) { size += sizeof(int16) * 3; // scanline size in bytes, Y, num_spans const scanline_data& sl_this = m_scanlines[i]; unsigned num_spans = sl_this.num_spans; unsigned span_idx = sl_this.start_span; do { const span_data& sp = m_spans[span_idx++]; size += sizeof(int16) * 2; // X, span_len if(sp.len < 0) { size += sizeof(T); // cover } else { size += sizeof(T) * unsigned(sp.len); // covers } } while(--num_spans); } return size; } //--------------------------------------------------------------- static void write_int16(int8u* dst, int16 val) { dst[0] = ((const int8u*)&val)[0]; dst[1] = ((const int8u*)&val)[1]; } //--------------------------------------------------------------- void serialize(int8u* data) const { unsigned i; write_int16(data, int16u(min_x())); // min_x data += sizeof(int16u); write_int16(data, int16u(min_y())); // min_y data += sizeof(int16u); write_int16(data, int16u(max_x())); // max_x data += sizeof(int16u); write_int16(data, int16u(max_y())); // max_y data += sizeof(int16u); for(i = 0; i < m_scanlines.size(); ++i) { const scanline_data& sl_this = m_scanlines[i]; int8u* size_ptr = data; data += sizeof(int16); // Reserve space for scanline size in bytes write_int16(data, int16(sl_this.y)); // Y data += sizeof(int16); write_int16(data, int16(sl_this.num_spans)); // num_spans data += sizeof(int16); unsigned num_spans = sl_this.num_spans; unsigned span_idx = sl_this.start_span; do { const span_data& sp = m_spans[span_idx++]; const T* covers = covers_by_index(sp.covers_id); write_int16(data, int16(sp.x)); // X data += sizeof(int16); write_int16(data, int16(sp.len)); // span_len data += sizeof(int16); if(sp.len < 0) { memcpy(data, covers, sizeof(T)); data += sizeof(T); } else { memcpy(data, covers, unsigned(sp.len) * sizeof(T)); data += sizeof(T) * unsigned(sp.len); } } while(--num_spans); write_int16(size_ptr, int16(unsigned(data - size_ptr))); } } //--------------------------------------------------------------- const scanline_data& scanline_by_index(unsigned i) const { return (i < m_scanlines.size()) ? m_scanlines[i] : m_fake_scanline; } //--------------------------------------------------------------- const span_data& span_by_index(unsigned i) const { return (i < m_spans.size()) ? m_spans[i] : m_fake_span; } //--------------------------------------------------------------- const T* covers_by_index(int i) const { return m_covers[i]; } private: scanline_cell_storage m_covers; pod_deque m_spans; pod_deque m_scanlines; span_data m_fake_span; scanline_data m_fake_scanline; int m_min_x; int m_min_y; int m_max_x; int m_max_y; unsigned m_cur_scanline; }; typedef scanline_storage_aa scanline_storage_aa8; //--------scanline_storage_aa8 typedef scanline_storage_aa scanline_storage_aa16; //--------scanline_storage_aa16 typedef scanline_storage_aa scanline_storage_aa32; //--------scanline_storage_aa32 //------------------------------------------serialized_scanlines_adaptor_aa template class serialized_scanlines_adaptor_aa { public: typedef T cover_type; //--------------------------------------------------------------------- class embedded_scanline { public: typedef T cover_type; //----------------------------------------------------------------- class const_iterator { public: struct span { int16 x; int16 len; // If negative, it's a solid span, "covers" is valid const T* covers; }; const_iterator(const embedded_scanline& sl) : m_ptr(sl.m_ptr), m_dx(sl.m_dx) { init_span(); } const span& operator*() const { return m_span; } const span* operator->() const { return &m_span; } void operator ++ () { if(m_span.len < 0) { m_ptr += sizeof(T); } else { m_ptr += m_span.len * sizeof(T); } init_span(); } private: int read_int16() { int16 val; ((int8u*)&val)[0] = *m_ptr++; ((int8u*)&val)[1] = *m_ptr++; return val; } void init_span() { m_span.x = read_int16() + m_dx; m_span.len = read_int16(); m_span.covers = m_ptr; } const int8u* m_ptr; span m_span; int m_dx; }; friend class const_iterator; //----------------------------------------------------------------- embedded_scanline() : m_ptr(0), m_y(0), m_num_spans(0) {} //----------------------------------------------------------------- void reset(int, int) {} unsigned num_spans() const { return m_num_spans; } int y() const { return m_y; } const_iterator begin() const { return const_iterator(*this); } private: //----------------------------------------------------------------- int read_int16() { int16 val; ((int8u*)&val)[0] = *m_ptr++; ((int8u*)&val)[1] = *m_ptr++; return val; } public: //----------------------------------------------------------------- void init(const int8u* ptr, int dx, int dy) { m_ptr = ptr; m_y = read_int16() + dy; m_num_spans = unsigned(read_int16()); m_dx = dx; } private: const int8u* m_ptr; int m_y; unsigned m_num_spans; int m_dx; }; public: //-------------------------------------------------------------------- serialized_scanlines_adaptor_aa() : m_data(0), m_end(0), m_ptr(0), m_dx(0), m_dy(0), m_min_x(0x7FFFFFFF), m_min_y(0x7FFFFFFF), m_max_x(-0x7FFFFFFF), m_max_y(-0x7FFFFFFF) {} //-------------------------------------------------------------------- serialized_scanlines_adaptor_aa(const int8u* data, unsigned size, double dx, double dy) : m_data(data), m_end(data + size), m_ptr(data), m_dx(int(floor(dx + 0.5))), m_dy(int(floor(dy + 0.5))), m_min_x(0x7FFFFFFF), m_min_y(0x7FFFFFFF), m_max_x(-0x7FFFFFFF), m_max_y(-0x7FFFFFFF) {} //-------------------------------------------------------------------- void init(const int8u* data, unsigned size, double dx, double dy) { m_data = data; m_end = data + size; m_ptr = data; m_dx = int(floor(dx + 0.5)); m_dy = int(floor(dy + 0.5)); m_min_x = 0x7FFFFFFF; m_min_y = 0x7FFFFFFF; m_max_x = -0x7FFFFFFF; m_max_y = -0x7FFFFFFF; } private: //-------------------------------------------------------------------- int read_int16() { int16 val; ((int8u*)&val)[0] = *m_ptr++; ((int8u*)&val)[1] = *m_ptr++; return val; } //-------------------------------------------------------------------- unsigned read_int16u() { int16u val; ((int8u*)&val)[0] = *m_ptr++; ((int8u*)&val)[1] = *m_ptr++; return val; } public: // Iterate scanlines interface //-------------------------------------------------------------------- bool rewind_scanlines() { m_ptr = m_data; if(m_ptr < m_end) { m_min_x = read_int16() + m_dx; m_min_y = read_int16() + m_dy; m_max_x = read_int16() + m_dx; m_max_y = read_int16() + m_dy; return true; } return false; } //-------------------------------------------------------------------- int min_x() const { return m_min_x; } int min_y() const { return m_min_y; } int max_x() const { return m_max_x; } int max_y() const { return m_max_y; } //-------------------------------------------------------------------- template bool sweep_scanline(Scanline& sl) { sl.reset_spans(); for(;;) { if(m_ptr >= m_end) return false; read_int16(); // Skip scanline size in bytes int y = read_int16() + m_dy; unsigned num_spans = read_int16(); do { int x = read_int16() + m_dx; int len = read_int16(); if(len < 0) { sl.add_span(x, unsigned(-len), *m_ptr); m_ptr += sizeof(T); } else { sl.add_cells(x, len, m_ptr); m_ptr += len * sizeof(T); } } while(--num_spans); if(sl.num_spans()) { sl.finalize(y); break; } } return true; } //-------------------------------------------------------------------- // Specialization for embedded_scanline bool sweep_scanline(embedded_scanline& sl) { do { if(m_ptr >= m_end) return false; unsigned byte_size = read_int16u(); sl.init(m_ptr, m_dx, m_dy); m_ptr += byte_size - sizeof(int16); } while(sl.num_spans() == 0); return true; } private: const int8u* m_data; const int8u* m_end; const int8u* m_ptr; int m_dx; int m_dy; int m_min_x; int m_min_y; int m_max_x; int m_max_y; }; typedef serialized_scanlines_adaptor_aa serialized_scanlines_adaptor_aa8; //----serialized_scanlines_adaptor_aa8 typedef serialized_scanlines_adaptor_aa serialized_scanlines_adaptor_aa16; //----serialized_scanlines_adaptor_aa16 typedef serialized_scanlines_adaptor_aa serialized_scanlines_adaptor_aa32; //----serialized_scanlines_adaptor_aa32 } #endif aggdraw-1.3.14/agg2/include/agg_scanline_storage_bin.h000066400000000000000000000427411417726601400226360ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_SCANLINE_STORAGE_BIN_INCLUDED #define AGG_SCANLINE_STORAGE_BIN_INCLUDED #include #include #include #include "agg_array.h" #include "agg_render_scanlines.h" namespace agg { //-----------------------------------------------scanline_storage_bin class scanline_storage_bin { public: //--------------------------------------------------------------- struct span_data { int16 x; int16 len; }; //--------------------------------------------------------------- struct scanline_data { int y; unsigned num_spans; unsigned start_span; }; //--------------------------------------------------------------- class embedded_scanline { public: //----------------------------------------------------------- class const_iterator { public: const_iterator(const embedded_scanline& sl) : m_storage(sl.m_storage), m_span_idx(sl.m_scanline.start_span) { m_span = m_storage->span_by_index(m_span_idx); } const span_data& operator*() const { return m_span; } const span_data* operator->() const { return &m_span; } void operator ++ () { ++m_span_idx; m_span = m_storage->span_by_index(m_span_idx); } private: const scanline_storage_bin* m_storage; unsigned m_span_idx; span_data m_span; }; friend class const_iterator; //----------------------------------------------------------- embedded_scanline(const scanline_storage_bin& storage) : m_storage(&storage) { setup(0); } //----------------------------------------------------------- void reset(int, int) {} unsigned num_spans() const { return m_scanline.num_spans; } int y() const { return m_scanline.y; } const_iterator begin() const { return const_iterator(*this); } //----------------------------------------------------------- void setup(unsigned scanline_idx) { m_scanline_idx = scanline_idx; m_scanline = m_storage->scanline_by_index(m_scanline_idx); } private: const scanline_storage_bin* m_storage; scanline_data m_scanline; unsigned m_scanline_idx; }; //--------------------------------------------------------------- scanline_storage_bin() : m_spans(256-2), // Block increment size m_scanlines(), m_min_x( 0x7FFFFFFF), m_min_y( 0x7FFFFFFF), m_max_x(-0x7FFFFFFF), m_max_y(-0x7FFFFFFF), m_cur_scanline(0) { m_fake_scanline.y = 0; m_fake_scanline.num_spans = 0; m_fake_scanline.start_span = 0; m_fake_span.x = 0; m_fake_span.len = 0; } // Renderer Interface //--------------------------------------------------------------- void prepare(unsigned) { m_scanlines.remove_all(); m_spans.remove_all(); m_min_x = 0x7FFFFFFF; m_min_y = 0x7FFFFFFF; m_max_x = -0x7FFFFFFF; m_max_y = -0x7FFFFFFF; m_cur_scanline = 0; } //--------------------------------------------------------------- template void render(const Scanline& sl) { scanline_data sl_this; int y = sl.y(); if(y < m_min_y) m_min_y = y; if(y > m_max_y) m_max_y = y; sl_this.y = y; sl_this.num_spans = sl.num_spans(); sl_this.start_span = m_spans.size(); typename Scanline::const_iterator span_iterator = sl.begin(); unsigned num_spans = sl_this.num_spans; do { span_data sp; sp.x = span_iterator->x; sp.len = (int16)abs((int)(span_iterator->len)); m_spans.add(sp); int x1 = sp.x; int x2 = sp.x + sp.len - 1; if(x1 < m_min_x) m_min_x = x1; if(x2 > m_max_x) m_max_x = x2; ++span_iterator; } while(--num_spans); m_scanlines.add(sl_this); } //--------------------------------------------------------------- // Iterate scanlines interface int min_x() const { return m_min_x; } int min_y() const { return m_min_y; } int max_x() const { return m_max_x; } int max_y() const { return m_max_y; } //--------------------------------------------------------------- bool rewind_scanlines() { m_cur_scanline = 0; return m_scanlines.size() > 0; } //--------------------------------------------------------------- template bool sweep_scanline(Scanline& sl) { sl.reset_spans(); for(;;) { if(m_cur_scanline >= m_scanlines.size()) return false; const scanline_data& sl_this = m_scanlines[m_cur_scanline]; unsigned num_spans = sl_this.num_spans; unsigned span_idx = sl_this.start_span; do { const span_data& sp = m_spans[span_idx++]; sl.add_span(sp.x, sp.len, cover_full); } while(--num_spans); ++m_cur_scanline; if(sl.num_spans()) { sl.finalize(sl_this.y); break; } } return true; } //--------------------------------------------------------------- // Specialization for embedded_scanline bool sweep_scanline(embedded_scanline& sl) { do { if(m_cur_scanline >= m_scanlines.size()) return false; sl.setup(m_cur_scanline); ++m_cur_scanline; } while(sl.num_spans() == 0); return true; } //--------------------------------------------------------------- unsigned byte_size() const { unsigned i; unsigned size = sizeof(int16) * 4; // min_x, min_y, max_x, max_y for(i = 0; i < m_scanlines.size(); ++i) { size += sizeof(int16) * 2; // Y, num_spans const scanline_data& sl_this = m_scanlines[i]; unsigned num_spans = sl_this.num_spans; unsigned span_idx = sl_this.start_span; do { const span_data& sp = m_spans[span_idx++]; size += sizeof(int16) * 2; // X, span_len } while(--num_spans); } return size; } //--------------------------------------------------------------- static void write_int16(int8u* dst, int16 val) { dst[0] = ((const int8u*)&val)[0]; dst[1] = ((const int8u*)&val)[1]; } //--------------------------------------------------------------- void serialize(int8u* data) const { unsigned i; write_int16(data, int16u(min_x())); // min_x data += sizeof(int16u); write_int16(data, int16u(min_y())); // min_y data += sizeof(int16u); write_int16(data, int16u(max_x())); // max_x data += sizeof(int16u); write_int16(data, int16u(max_y())); // max_y data += sizeof(int16u); for(i = 0; i < m_scanlines.size(); ++i) { const scanline_data& sl_this = m_scanlines[i]; write_int16(data, int16(sl_this.y)); // Y data += sizeof(int16); write_int16(data, int16(sl_this.num_spans)); // num_spans data += sizeof(int16); unsigned num_spans = sl_this.num_spans; unsigned span_idx = sl_this.start_span; do { const span_data& sp = m_spans[span_idx++]; write_int16(data, int16(sp.x)); // X data += sizeof(int16); write_int16(data, int16(sp.len)); // len data += sizeof(int16); } while(--num_spans); } } //--------------------------------------------------------------- const scanline_data& scanline_by_index(unsigned i) const { return (i < m_scanlines.size()) ? m_scanlines[i] : m_fake_scanline; } //--------------------------------------------------------------- const span_data& span_by_index(unsigned i) const { return (i < m_spans.size()) ? m_spans[i] : m_fake_span; } private: pod_deque m_spans; pod_deque m_scanlines; span_data m_fake_span; scanline_data m_fake_scanline; int m_min_x; int m_min_y; int m_max_x; int m_max_y; unsigned m_cur_scanline; }; //---------------------------------------serialized_scanlines_adaptor_bin class serialized_scanlines_adaptor_bin { public: typedef bool cover_type; //-------------------------------------------------------------------- class embedded_scanline { public: //---------------------------------------------------------------- class const_iterator { public: struct span { int16 x; int16 len; }; const_iterator(const embedded_scanline& sl) : m_ptr(sl.m_ptr), m_dx(sl.m_dx) { m_span.x = read_int16() + m_dx; m_span.len = read_int16(); } const span& operator*() const { return m_span; } const span* operator->() const { return &m_span; } void operator ++ () { m_span.x = read_int16() + m_dx; m_span.len = read_int16(); } private: int read_int16() { int16 val; ((int8u*)&val)[0] = *m_ptr++; ((int8u*)&val)[1] = *m_ptr++; return val; } const int8u* m_ptr; span m_span; int m_dx; }; friend class const_iterator; //---------------------------------------------------------------- embedded_scanline() : m_ptr(0), m_y(0), m_num_spans(0) {} //---------------------------------------------------------------- void reset(int, int) {} unsigned num_spans() const { return m_num_spans; } int y() const { return m_y; } const_iterator begin() const { return const_iterator(*this); } private: //---------------------------------------------------------------- int read_int16() { int16 val; ((int8u*)&val)[0] = *m_ptr++; ((int8u*)&val)[1] = *m_ptr++; return val; } public: //---------------------------------------------------------------- void init(const int8u* ptr, int dx, int dy) { m_ptr = ptr; m_y = read_int16() + dy; m_num_spans = unsigned(read_int16()); m_dx = dx; } private: const int8u* m_ptr; int m_y; unsigned m_num_spans; int m_dx; }; public: //-------------------------------------------------------------------- serialized_scanlines_adaptor_bin() : m_data(0), m_end(0), m_ptr(0), m_dx(0), m_dy(0), m_min_x(0x7FFFFFFF), m_min_y(0x7FFFFFFF), m_max_x(-0x7FFFFFFF), m_max_y(-0x7FFFFFFF) {} //-------------------------------------------------------------------- serialized_scanlines_adaptor_bin(const int8u* data, unsigned size, double dx, double dy) : m_data(data), m_end(data + size), m_ptr(data), m_dx(int(floor(dx + 0.5))), m_dy(int(floor(dy + 0.5))), m_min_x(0x7FFFFFFF), m_min_y(0x7FFFFFFF), m_max_x(-0x7FFFFFFF), m_max_y(-0x7FFFFFFF) {} //-------------------------------------------------------------------- void init(const int8u* data, unsigned size, double dx, double dy) { m_data = data; m_end = data + size; m_ptr = data; m_dx = int(floor(dx + 0.5)); m_dy = int(floor(dy + 0.5)); m_min_x = 0x7FFFFFFF; m_min_y = 0x7FFFFFFF; m_max_x = -0x7FFFFFFF; m_max_y = -0x7FFFFFFF; } private: //-------------------------------------------------------------------- int read_int16() { int16 val; ((int8u*)&val)[0] = *m_ptr++; ((int8u*)&val)[1] = *m_ptr++; return val; } public: // Iterate scanlines interface //-------------------------------------------------------------------- bool rewind_scanlines() { m_ptr = m_data; if(m_ptr < m_end) { m_min_x = read_int16() + m_dx; m_min_y = read_int16() + m_dy; m_max_x = read_int16() + m_dx; m_max_y = read_int16() + m_dy; return true; } return false; } //-------------------------------------------------------------------- int min_x() const { return m_min_x; } int min_y() const { return m_min_y; } int max_x() const { return m_max_x; } int max_y() const { return m_max_y; } //-------------------------------------------------------------------- template bool sweep_scanline(Scanline& sl) { sl.reset_spans(); for(;;) { if(m_ptr >= m_end) return false; int y = read_int16() + m_dy; unsigned num_spans = read_int16(); do { int x = read_int16() + m_dx; int len = read_int16(); if(len < 0) len = -len; sl.add_span(x, unsigned(len), cover_full); } while(--num_spans); if(sl.num_spans()) { sl.finalize(y); break; } } return true; } //-------------------------------------------------------------------- // Specialization for embedded_scanline bool sweep_scanline(embedded_scanline& sl) { do { if(m_ptr >= m_end) return false; sl.init(m_ptr, m_dx, m_dy); // Jump to the next scanline //-------------------------- read_int16(); // Y int num_spans = read_int16(); // num_spans m_ptr += num_spans * sizeof(int16) * 2; } while(sl.num_spans() == 0); return true; } private: const int8u* m_data; const int8u* m_end; const int8u* m_ptr; int m_dx; int m_dy; int m_min_x; int m_min_y; int m_max_x; int m_max_y; }; } #endif aggdraw-1.3.14/agg2/include/agg_scanline_u.h000066400000000000000000000261441417726601400206050ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_SCANLINE_U_INCLUDED #define AGG_SCANLINE_U_INCLUDED #include #include "agg_basics.h" namespace agg { //==============================================================scanline_u // // Unpacked scanline container class // // This class is used to transfer data from a scanline rastyerizer // to the rendering buffer. It's organized very simple. The class stores // information of horizontal spans to render it into a pixel-map buffer. // Each span has staring X, length, and an array of bytes that determine the // cover-values for each pixel. // Before using this class you should know the minimal and maximal pixel // coordinates of your scanline. The protocol of using is: // 1. reset(min_x, max_x) // 2. add_cell() / add_span() - accumulate scanline. // When forming one scanline the next X coordinate must be always greater // than the last stored one, i.e. it works only with ordered coordinates. // 3. Call finalize(y) and render the scanline. // 3. Call reset_spans() to prepare for the new scanline. // // 4. Rendering: // // Scanline provides an iterator class that allows you to extract // the spans and the cover values for each pixel. Be aware that clipping // has not been done yet, so you should perform it yourself. // Use scanline_u8::iterator to render spans: //------------------------------------------------------------------------- // // int y = sl.y(); // Y-coordinate of the scanline // // ************************************ // ...Perform vertical clipping here... // ************************************ // // scanline_u8::const_iterator span = sl.begin(); // // unsigned char* row = m_rbuf->row(y); // The the address of the beginning // // of the current row // // unsigned num_spans = sl.num_spans(); // Number of spans. It's guaranteed that // // num_spans is always greater than 0. // // do // { // const scanline_u8::cover_type* covers = // span->covers; // The array of the cover values // // int num_pix = span->len; // Number of pixels of the span. // // Always greater than 0, still it's // // better to use "int" instead of // // "unsigned" because it's more // // convenient for clipping // int x = span->x; // // ************************************** // ...Perform horizontal clipping here... // ...you have x, covers, and pix_count.. // ************************************** // // unsigned char* dst = row + x; // Calculate the start address of the row. // // In this case we assume a simple // // grayscale image 1-byte per pixel. // do // { // *dst++ = *covers++; // Hypotetical rendering. // } // while(--num_pix); // // ++span; // } // while(--num_spans); // num_spans cannot be 0, so this loop is quite safe //------------------------------------------------------------------------ // // The question is: why should we accumulate the whole scanline when we // could render just separate spans when they're ready? // That's because using the scaline is generally faster. When is consists // of more than one span the conditions for the processor cash system // are better, because switching between two different areas of memory // (that can be very large) occures less frequently. //------------------------------------------------------------------------ template class scanline_u { public: typedef T cover_type; //-------------------------------------------------------------------- struct span { int16 x; int16 len; cover_type* covers; }; typedef span* iterator; typedef const span* const_iterator; //-------------------------------------------------------------------- ~scanline_u(); scanline_u(); void reset(int min_x, int max_x); void add_cell(int x, unsigned cover); void add_cells(int x, unsigned len, const T* covers); void add_span(int x, unsigned len, unsigned cover); void finalize(int y) { m_y = y; } void reset_spans(); int y() const { return m_y; } unsigned num_spans() const { return unsigned(m_cur_span - m_spans); } const_iterator begin() const { return m_spans + 1; } iterator begin() { return m_spans + 1; } private: scanline_u(const scanline_u&); const scanline_u& operator = (const scanline_u&); private: int m_min_x; unsigned m_max_len; int m_last_x; int m_y; cover_type* m_covers; span* m_spans; span* m_cur_span; }; //------------------------------------------------------------------------ template scanline_u::~scanline_u() { delete [] m_spans; delete [] m_covers; } //------------------------------------------------------------------------ template scanline_u::scanline_u() : m_min_x(0), m_max_len(0), m_last_x(0x7FFFFFF0), m_covers(0), m_spans(0), m_cur_span(0) { } //------------------------------------------------------------------------ template void scanline_u::reset(int min_x, int max_x) { unsigned max_len = max_x - min_x + 2; if(max_len > m_max_len) { delete [] m_spans; delete [] m_covers; m_covers = new cover_type [max_len]; m_spans = new span [max_len]; m_max_len = max_len; } m_last_x = 0x7FFFFFF0; m_min_x = min_x; m_cur_span = m_spans; } //------------------------------------------------------------------------ template inline void scanline_u::reset_spans() { m_last_x = 0x7FFFFFF0; m_cur_span = m_spans; } //------------------------------------------------------------------------ template inline void scanline_u::add_cell(int x, unsigned cover) { x -= m_min_x; m_covers[x] = (unsigned char)cover; if(x == m_last_x+1) { m_cur_span->len++; } else { m_cur_span++; m_cur_span->x = (int16)(x + m_min_x); m_cur_span->len = 1; m_cur_span->covers = m_covers + x; } m_last_x = x; } //------------------------------------------------------------------------ template void scanline_u::add_cells(int x, unsigned len, const T* covers) { x -= m_min_x; memcpy(m_covers + x, covers, len * sizeof(T)); if(x == m_last_x+1) { m_cur_span->len += (int16)len; } else { m_cur_span++; m_cur_span->x = (int16)(x + m_min_x); m_cur_span->len = (int16)len; m_cur_span->covers = m_covers + x; } m_last_x = x + len - 1; } //------------------------------------------------------------------------ template void scanline_u::add_span(int x, unsigned len, unsigned cover) { x -= m_min_x; memset(m_covers + x, cover, len); if(x == m_last_x+1) { m_cur_span->len += (int16)len; } else { m_cur_span++; m_cur_span->x = (int16)(x + m_min_x); m_cur_span->len = (int16)len; m_cur_span->covers = m_covers + x; } m_last_x = x + len - 1; } //=============================================================scanline_u8 typedef scanline_u scanline_u8; //============================================================scanline_u16 typedef scanline_u scanline_u16; //============================================================scanline_u32 typedef scanline_u scanline_u32; //=============================================================scanline_am // // The scanline container with alpha-masking // //------------------------------------------------------------------------ template class scanline_am : public scanline_u { public: typedef AlphaMask alpha_mask_type; typedef CoverT cover_type; typedef scanline_u scanline_type; scanline_am() : scanline_type(), m_alpha_mask(0) {} scanline_am(const AlphaMask& am) : scanline_type(), m_alpha_mask(&am) {} //-------------------------------------------------------------------- void finalize(int span_y) { scanline_u::finalize(span_y); if(m_alpha_mask) { typename scanline_type::iterator span = scanline_type::begin(); unsigned count = scanline_type::num_spans(); do { m_alpha_mask->combine_hspan(span->x, scanline_type::y(), span->covers, span->len); ++span; } while(--count); } } private: const AlphaMask* m_alpha_mask; }; //==========================================================scanline_u8_am template class scanline_u8_am : public scanline_am { public: typedef AlphaMask alpha_mask_type; typedef int8u cover_type; typedef scanline_am self_type; scanline_u8_am() : self_type() {} scanline_u8_am(const AlphaMask& am) : self_type(am) {} }; } #endif aggdraw-1.3.14/agg2/include/agg_shorten_path.h000066400000000000000000000037601417726601400211620ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_SHORTEN_PATH_INCLUDED #define AGG_SHORTEN_PATH_INCLUDED #include "agg_basics.h" #include "agg_vertex_sequence.h" namespace agg { //===========================================================shorten_path template void shorten_path(VertexSequence& vs, double s, unsigned closed = 0) { typedef typename VertexSequence::value_type vertex_type; if(s > 0.0 && vs.size() > 1) { double d; int n = int(vs.size() - 2); while(n) { d = vs[n].dist; if(d > s) break; vs.remove_last(); s -= d; --n; } if(vs.size() < 2) { vs.remove_all(); } else { n = vs.size() - 1; vertex_type& prev = vs[n-1]; vertex_type& last = vs[n]; d = (prev.dist - s) / prev.dist; double x = prev.x + (last.x - prev.x) * d; double y = prev.y + (last.y - prev.y) * d; last.x = x; last.y = y; if(!prev(last)) vs.remove_last(); vs.close(closed != 0); } } } } #endif aggdraw-1.3.14/agg2/include/agg_simul_eq.h000066400000000000000000000076411417726601400203040ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Solving simultaneous equations // //---------------------------------------------------------------------------- #ifndef AGG_SIMUL_EQ_INCLUDED #define AGG_SIMUL_EQ_INCLUDED #include #include "agg_basics.h" namespace agg { //=============================================================swap_arrays template void swap_arrays(T* a1, T* a2, unsigned n) { unsigned i; for(i = 0; i < n; i++) { T tmp = *a1; *a1++ = *a2; *a2++ = tmp; } } //============================================================matrix_pivot template struct matrix_pivot { static int pivot(double m[Rows][Cols], unsigned row) { int k = int(row); double max_val, tmp; max_val = -1.0; unsigned i; for(i = row; i < Rows; i++) { if((tmp = fabs(m[i][row])) > max_val && tmp != 0.0) { max_val = tmp; k = i; } } if(m[k][row] == 0.0) { return -1; } if(k != int(row)) { swap_arrays(m[k], m[row], Cols); return k; } return 0; } }; //===============================================================simul_eq template struct simul_eq { static bool solve(const double left[Size][Size], const double right[Size][RightCols], double result[Size][RightCols]) { unsigned i, j, k; double a1; double tmp[Size][Size + RightCols]; for(i = 0; i < Size; i++) { for(j = 0; j < Size; j++) { tmp[i][j] = left[i][j]; } for(j = 0; j < RightCols; j++) { tmp[i][Size + j] = right[i][j]; } } for(k = 0; k < Size; k++) { if(matrix_pivot::pivot(tmp, k) < 0) { return false; // Singularity.... } a1 = tmp[k][k]; for(j = k; j < Size + RightCols; j++) { tmp[k][j] /= a1; } for(i = k + 1; i < Size; i++) { a1 = tmp[i][k]; for (j = k; j < Size + RightCols; j++) { tmp[i][j] -= a1 * tmp[k][j]; } } } for(k = 0; k < RightCols; k++) { int m; for(m = int(Size - 1); m >= 0; m--) { result[m][k] = tmp[m][Size + k]; for(j = m + 1; j < Size; j++) { result[m][k] -= tmp[m][j] * result[j][k]; } } } return true; } }; } #endif aggdraw-1.3.14/agg2/include/agg_span_allocator.h000066400000000000000000000042141417726601400214600ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_SPAN_ALLOCATOR_INCLUDED #define AGG_SPAN_ALLOCATOR_INCLUDED #include "agg_basics.h" namespace agg { //----------------------------------------------------------span_allocator template class span_allocator { public: typedef ColorT color_type; //-------------------------------------------------------------------- ~span_allocator() { delete [] m_span; } //-------------------------------------------------------------------- span_allocator() : m_max_span_len(0), m_span(0) { } //-------------------------------------------------------------------- color_type* allocate(unsigned max_span_len) { if(max_span_len > m_max_span_len) { delete [] m_span; m_span = new color_type[m_max_span_len = max_span_len]; } return m_span; } //-------------------------------------------------------------------- color_type* span() { return m_span; } private: //-------------------------------------------------------------------- span_allocator(const span_allocator&); const span_allocator& operator = (const span_allocator&); unsigned m_max_span_len; color_type* m_span; }; } #endif aggdraw-1.3.14/agg2/include/agg_span_converter.h000066400000000000000000000033411417726601400215070ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_SPAN_CONVERTER_INCLUDED #define AGG_SPAN_CONVERTER_INCLUDED #include "agg_basics.h" namespace agg { //----------------------------------------------------------span_converter template class span_converter { public: typedef typename SpanGenerator::color_type color_type; span_converter(SpanGenerator& span_gen, Conv& conv) : m_span_gen(&span_gen), m_conv(&conv) {} //-------------------------------------------------------------------- void prepare(unsigned max_span_len) { m_span_gen->prepare(max_span_len); } //-------------------------------------------------------------------- color_type* generate(int x, int y, unsigned len) { color_type* span = m_span_gen->generate(x, y, len); m_conv->convert(span, len); return span; } private: SpanGenerator* m_span_gen; Conv* m_conv; }; } #endif aggdraw-1.3.14/agg2/include/agg_span_generator.h000066400000000000000000000032441417726601400214700ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_SPAN_GENERATOR_INCLUDED #define AGG_SPAN_GENERATOR_INCLUDED #include "agg_basics.h" #include "agg_span_allocator.h" namespace agg { //==========================================================span_generator template class span_generator { public: typedef ColorT color_type; typedef Allocator alloc_type; //-------------------------------------------------------------------- span_generator(alloc_type& alloc) : m_alloc(&alloc) {} //-------------------------------------------------------------------- void allocator(alloc_type& alloc) { m_alloc = &alloc; } alloc_type& allocator() { return *m_alloc; } //-------------------------------------------------------------------- void prepare(unsigned max_span_len) { m_alloc->allocate(max_span_len); } private: alloc_type* m_alloc; }; } #endif aggdraw-1.3.14/agg2/include/agg_span_gouraud.h000066400000000000000000000135771417726601400211620ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_SPAN_GOURAUD_INCLUDED #define AGG_SPAN_GOURAUD_INCLUDED #include "agg_basics.h" #include "agg_math.h" #include "agg_span_generator.h" namespace agg { //============================================================span_gouraud template class span_gouraud : public span_generator { public: typedef ColorT color_type; typedef Allocator alloc_type; struct coord_type { double x; double y; color_type color; }; //-------------------------------------------------------------------- span_gouraud(alloc_type& alloc) : span_generator(alloc), m_vertex(0) { m_cmd[0] = path_cmd_stop; } //-------------------------------------------------------------------- span_gouraud(alloc_type& alloc, const color_type& c1, const color_type& c2, const color_type& c3, double x1, double y1, double x2, double y2, double x3, double y3, double d) : span_generator(alloc) { colors(c1, c2, c3); triangle(x1, y1, x2, y2, x3, y3, d); } //-------------------------------------------------------------------- void colors(ColorT c1, ColorT c2, ColorT c3) { m_coord[0].color = c1; m_coord[1].color = c2; m_coord[2].color = c3; } //-------------------------------------------------------------------- // Sets the triangle and dilates it if needed. // The trick here is to calculate beveled joins in the vertices of the // triangle and render it as a 6-vertex polygon. // It's necessary to achieve numerical stability. // However, the coordinates to interpolate colors are calculated // as miter joins (calc_intersection). void triangle(double x1, double y1, double x2, double y2, double x3, double y3, double d) { m_coord[0].x = m_x[0] = x1; m_coord[0].y = m_y[0] = y1; m_coord[1].x = m_x[1] = x2; m_coord[1].y = m_y[1] = y2; m_coord[2].x = m_x[2] = x3; m_coord[2].y = m_y[2] = y3; m_cmd[0] = path_cmd_move_to; m_cmd[1] = path_cmd_line_to; m_cmd[2] = path_cmd_line_to; m_cmd[3] = path_cmd_stop; if(d != 0.0) { dilate_triangle(m_coord[0].x, m_coord[0].y, m_coord[1].x, m_coord[1].y, m_coord[2].x, m_coord[2].y, m_x, m_y, d); calc_intersection(m_x[4], m_y[4], m_x[5], m_y[5], m_x[0], m_y[0], m_x[1], m_y[1], &m_coord[0].x, &m_coord[0].y); calc_intersection(m_x[0], m_y[0], m_x[1], m_y[1], m_x[2], m_y[2], m_x[3], m_y[3], &m_coord[1].x, &m_coord[1].y); calc_intersection(m_x[2], m_y[2], m_x[3], m_y[3], m_x[4], m_y[4], m_x[5], m_y[5], &m_coord[2].x, &m_coord[2].y); m_cmd[3] = path_cmd_line_to; m_cmd[4] = path_cmd_line_to; m_cmd[5] = path_cmd_line_to; m_cmd[6] = path_cmd_stop; } } //-------------------------------------------------------------------- // Vertex Source Interface to feed the coordinates to the rasterizer void rewind(unsigned) { m_vertex = 0; } //-------------------------------------------------------------------- unsigned vertex(double* x, double* y) { *x = m_x[m_vertex]; *y = m_y[m_vertex]; return m_cmd[m_vertex++]; } protected: //-------------------------------------------------------------------- void arrange_vertices(coord_type* coord) const { coord[0] = m_coord[0]; coord[1] = m_coord[1]; coord[2] = m_coord[2]; if(m_coord[0].y > m_coord[2].y) { coord[0] = m_coord[2]; coord[2] = m_coord[0]; } coord_type tmp; if(coord[0].y > coord[1].y) { tmp = coord[1]; coord[1] = coord[0]; coord[0] = tmp; } if(coord[1].y > coord[2].y) { tmp = coord[2]; coord[2] = coord[1]; coord[1] = tmp; } } private: //-------------------------------------------------------------------- coord_type m_coord[3]; double m_x[8]; double m_y[8]; unsigned m_cmd[8]; unsigned m_vertex; }; } #endif aggdraw-1.3.14/agg2/include/agg_span_gouraud_gray8.h000066400000000000000000000122221417726601400222560ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_SPAN_GOURAUD_GRAY8_INCLUDED #define AGG_SPAN_GOURAUD_GRAY8_INCLUDED #include "agg_basics.h" #include "agg_gray8.h" #include "agg_dda_line.h" #include "agg_span_gouraud.h" namespace agg { //======================================================span_gouraud_gray8 template > class span_gouraud_gray8 : public span_gouraud { public: typedef Allocator alloc_type; typedef gray8 color_type; typedef span_gouraud base_type; typedef typename base_type::coord_type coord_type; private: //-------------------------------------------------------------------- struct gray_calc { void init(const coord_type& c1, const coord_type& c2) { m_x1 = c1.x; m_y1 = c1.y; m_dx = c2.x - c1.x; m_dy = 1.0 / (c2.y - c1.y); m_v1 = c1.color.v; m_a1 = c1.color.a; m_dv = c2.color.v - m_v1; m_da = c2.color.a - m_a1; } void calc(int y) { double k = 0.0; if(y > m_y1) k = (y - m_y1) * m_dy; gray8 c; m_v = m_v1 + int(m_dv * k); m_a = m_a1 + int(m_da * k); m_x = int(m_x1 + m_dx * k); } double m_x1; double m_y1; double m_dx; double m_dy; int m_v1; int m_a1; int m_dv; int m_da; int m_v; int m_a; int m_x; }; public: //-------------------------------------------------------------------- span_gouraud_gray8(alloc_type& alloc) : base_type(alloc) {} //-------------------------------------------------------------------- span_gouraud_gray8(alloc_type& alloc, const color_type& c1, const color_type& c2, const color_type& c3, double x1, double y1, double x2, double y2, double x3, double y3, double d = 0) : base_type(alloc, c1, c2, c3, x1, y1, x2, y2, x3, y3, d) {} //-------------------------------------------------------------------- void prepare(unsigned max_span_len) { base_type::prepare(max_span_len); coord_type coord[3]; arrange_vertices(coord); m_y2 = int(coord[1].y); m_swap = calc_point_location(coord[0].x, coord[0].y, coord[2].x, coord[2].y, coord[1].x, coord[1].y) < 0.0; m_c1.init(coord[0], coord[2]); m_c2.init(coord[0], coord[1]); m_c3.init(coord[1], coord[2]); } //-------------------------------------------------------------------- color_type* generate(int x, int y, unsigned len) { m_c1.calc(y); const gray_calc* pc1 = &m_c1; const gray_calc* pc2 = &m_c2; if(y < m_y2) { m_c2.calc(y+1); } else { m_c3.calc(y); pc2 = &m_c3; } if(m_swap) { const gray_calc* t = pc2; pc2 = pc1; pc1 = t; } int nx = pc1->m_x; unsigned nlen = pc2->m_x - pc1->m_x + 1; if(nlen < len) nlen = len; dda_line_interpolator<16> v(pc1->m_v, pc2->m_v, nlen); dda_line_interpolator<16> a(pc1->m_a, pc2->m_a, nlen); if(nx < x) { unsigned d = unsigned(x - nx); v += d; a += d; } color_type* span = base_type::allocator().span(); do { span->v = v.y(); span->a = a.y(); ++v; ++a; ++span; } while(--len); return base_type::allocator().span(); } private: bool m_swap; int m_y2; gray_calc m_c1; gray_calc m_c2; gray_calc m_c3; }; } #endif aggdraw-1.3.14/agg2/include/agg_span_gouraud_rgba8.h000066400000000000000000000136101417726601400222310ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_SPAN_GOURAUD_RGBA8_INCLUDED #define AGG_SPAN_GOURAUD_RGBA8_INCLUDED #include "agg_basics.h" #include "agg_color_rgba8.h" #include "agg_dda_line.h" #include "agg_span_gouraud.h" namespace agg { //======================================================span_gouraud_rgba8 template > class span_gouraud_rgba8 : public span_gouraud { public: typedef Allocator alloc_type; typedef rgba8 color_type; typedef span_gouraud base_type; typedef typename base_type::coord_type coord_type; private: //-------------------------------------------------------------------- struct rgba_calc { void init(const coord_type& c1, const coord_type& c2) { m_x1 = c1.x; m_y1 = c1.y; m_dx = c2.x - c1.x; m_dy = 1.0 / (c2.y - c1.y); m_r1 = c1.color.r; m_g1 = c1.color.g; m_b1 = c1.color.b; m_a1 = c1.color.a; m_dr = c2.color.r - m_r1; m_dg = c2.color.g - m_g1; m_db = c2.color.b - m_b1; m_da = c2.color.a - m_a1; } void calc(int y) { double k = 0.0; if(y > m_y1) k = (y - m_y1) * m_dy; rgba8 rgba; m_r = m_r1 + int(m_dr * k); m_g = m_g1 + int(m_dg * k); m_b = m_b1 + int(m_db * k); m_a = m_a1 + int(m_da * k); m_x = int(m_x1 + m_dx * k); } double m_x1; double m_y1; double m_dx; double m_dy; int m_r1; int m_g1; int m_b1; int m_a1; int m_dr; int m_dg; int m_db; int m_da; int m_r; int m_g; int m_b; int m_a; int m_x; }; public: //-------------------------------------------------------------------- span_gouraud_rgba8(alloc_type& alloc) : base_type(alloc) {} //-------------------------------------------------------------------- span_gouraud_rgba8(alloc_type& alloc, const color_type& c1, const color_type& c2, const color_type& c3, double x1, double y1, double x2, double y2, double x3, double y3, double d = 0) : base_type(alloc, c1, c2, c3, x1, y1, x2, y2, x3, y3, d) {} //-------------------------------------------------------------------- void prepare(unsigned max_span_len) { base_type::prepare(max_span_len); coord_type coord[3]; arrange_vertices(coord); m_y2 = int(coord[1].y); m_swap = calc_point_location(coord[0].x, coord[0].y, coord[2].x, coord[2].y, coord[1].x, coord[1].y) < 0.0; m_rgba1.init(coord[0], coord[2]); m_rgba2.init(coord[0], coord[1]); m_rgba3.init(coord[1], coord[2]); } //-------------------------------------------------------------------- color_type* generate(int x, int y, unsigned len) { m_rgba1.calc(y); const rgba_calc* pc1 = &m_rgba1; const rgba_calc* pc2 = &m_rgba2; if(y < m_y2) { m_rgba2.calc(y+1); } else { m_rgba3.calc(y); pc2 = &m_rgba3; } if(m_swap) { const rgba_calc* t = pc2; pc2 = pc1; pc1 = t; } int nx = pc1->m_x; unsigned nlen = pc2->m_x - pc1->m_x + 1; if(nlen < len) nlen = len; dda_line_interpolator<16> r(pc1->m_r, pc2->m_r, nlen); dda_line_interpolator<16> g(pc1->m_g, pc2->m_g, nlen); dda_line_interpolator<16> b(pc1->m_b, pc2->m_b, nlen); dda_line_interpolator<16> a(pc1->m_a, pc2->m_a, nlen); if(nx < x) { unsigned d = unsigned(x - nx); r += d; g += d; b += d; a += d; } color_type* span = base_type::allocator().span(); do { span->r = (int8u)r.y(); span->g = (int8u)g.y(); span->b = (int8u)b.y(); span->a = (int8u)a.y(); ++r; ++g; ++b; ++a; ++span; } while(--len); return base_type::allocator().span(); } private: bool m_swap; int m_y2; rgba_calc m_rgba1; rgba_calc m_rgba2; rgba_calc m_rgba3; }; } #endif aggdraw-1.3.14/agg2/include/agg_span_gouraud_rgba8_gamma.h000066400000000000000000000151041417726601400233730ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_SPAN_GOURAUD_RGBA8_GAMMA_INCLUDED #define AGG_SPAN_GOURAUD_RGBA8_GAMMA_INCLUDED #include "agg_basics.h" #include "agg_color_rgba8.h" #include "agg_dda_line.h" #include "agg_span_gouraud.h" #include "agg_gamma_lut.h" namespace agg { //======================================================span_gouraud_rgba8 template, class Gamma = gamma_lut > class span_gouraud_rgba8_gamma : public span_gouraud { public: typedef Allocator alloc_type; typedef rgba8 color_type; typedef span_gouraud base_type; typedef typename base_type::coord_type coord_type; typedef Gamma gamma_type; private: //-------------------------------------------------------------------- struct rgba_calc { void init(const coord_type& c1, const coord_type& c2, const gamma_type& gamma) { m_x1 = c1.x; m_y1 = c1.y; m_dx = c2.x - c1.x; m_dy = 1.0 / (c2.y - c1.y); m_r1 = gamma.dir(c1.color.r); m_g1 = gamma.dir(c1.color.g); m_b1 = gamma.dir(c1.color.b); m_a1 = c1.color.a; m_dr = gamma.dir(c2.color.r) - m_r1; m_dg = gamma.dir(c2.color.g) - m_g1; m_db = gamma.dir(c2.color.b) - m_b1; m_da = c2.color.a - m_a1; } void calc(int y) { double k = 0.0; if(y > m_y1) k = (y - m_y1) * m_dy; m_r = m_r1 + int(m_dr * k); m_g = m_g1 + int(m_dg * k); m_b = m_b1 + int(m_db * k); m_a = m_a1 + int(m_da * k); m_x = int(m_x1 + m_dx * k); } double m_x1; double m_y1; double m_dx; double m_dy; int m_r1; int m_g1; int m_b1; int m_a1; int m_dr; int m_dg; int m_db; int m_da; int m_r; int m_g; int m_b; int m_a; int m_x; }; public: //-------------------------------------------------------------------- span_gouraud_rgba8_gamma(alloc_type& alloc, const gamma_type& g) : base_type(alloc), m_gamma(&g) {} //-------------------------------------------------------------------- span_gouraud_rgba8_gamma(alloc_type& alloc, const gamma_type& g, const color_type& c1, const color_type& c2, const color_type& c3, double x1, double y1, double x2, double y2, double x3, double y3, double d = 0) : base_type(alloc, c1, c2, c3, x1, y1, x2, y2, x3, y3, d), m_gamma(&g) {} //-------------------------------------------------------------------- void gamma(const gamma_type& g) { m_gamma = &g; } const gamma_type& gamma() const { return *m_gamma; } //-------------------------------------------------------------------- void prepare(unsigned max_span_len) { base_type::prepare(max_span_len); coord_type coord[3]; arrange_vertices(coord); m_y2 = int(coord[1].y); m_swap = calc_point_location(coord[0].x, coord[0].y, coord[2].x, coord[2].y, coord[1].x, coord[1].y) < 0.0; m_rgba1.init(coord[0], coord[2], *m_gamma); m_rgba2.init(coord[0], coord[1], *m_gamma); m_rgba3.init(coord[1], coord[2], *m_gamma); } //-------------------------------------------------------------------- color_type* generate(int x, int y, unsigned len) { m_rgba1.calc(y); const rgba_calc* pc1 = &m_rgba1; const rgba_calc* pc2 = &m_rgba2; if(y < m_y2) { m_rgba2.calc(y+1); } else { m_rgba3.calc(y); pc2 = &m_rgba3; } if(m_swap) { const rgba_calc* t = pc2; pc2 = pc1; pc1 = t; } int nx = pc1->m_x; unsigned nlen = pc2->m_x - pc1->m_x + 1; if(nlen < len) nlen = len; dda_line_interpolator<8> r(pc1->m_r, pc2->m_r, nlen); dda_line_interpolator<8> g(pc1->m_g, pc2->m_g, nlen); dda_line_interpolator<8> b(pc1->m_b, pc2->m_b, nlen); dda_line_interpolator<16> a(pc1->m_a, pc2->m_a, nlen); if(nx < x) { unsigned d = unsigned(x - nx); r += d; g += d; b += d; a += d; } color_type* span = base_type::allocator().span(); do { span->r = m_gamma->inv(r.y()); span->g = m_gamma->inv(g.y()); span->b = m_gamma->inv(b.y()); span->a = a.y(); ++r; ++g; ++b; ++a; ++span; } while(--len); return base_type::allocator().span(); } private: const gamma_type* m_gamma; bool m_swap; int m_y2; rgba_calc m_rgba1; rgba_calc m_rgba2; rgba_calc m_rgba3; }; } #endif aggdraw-1.3.14/agg2/include/agg_span_gradient.h000066400000000000000000000156311417726601400213020ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_SPAN_GRADIENT_INCLUDED #define AGG_SPAN_GRADIENT_INCLUDED #include #include #include "agg_basics.h" #include "agg_span_generator.h" #include "agg_math.h" namespace agg { //==========================================================span_gradient template > class span_gradient : public span_generator { public: typedef Interpolator interpolator_type; typedef Allocator alloc_type; typedef ColorT color_type; typedef span_generator base_type; enum { base_shift = 8, base_size = 1 << base_shift, base_mask = base_size - 1, gradient_shift = 4, gradient_size = 1 << gradient_shift, gradient_mask = gradient_size - 1, downscale_shift = interpolator_type::subpixel_shift - gradient_shift }; //-------------------------------------------------------------------- span_gradient(alloc_type& alloc) : base_type(alloc) {} //-------------------------------------------------------------------- span_gradient(alloc_type& alloc, interpolator_type& inter, const GradientF& gradient_function, ColorF color_function, double d1, double d2) : base_type(alloc), m_interpolator(&inter), m_gradient_function(&gradient_function), m_color_function(color_function), m_d1(int(d1 * gradient_size)), m_d2(int(d2 * gradient_size)) {} //-------------------------------------------------------------------- interpolator_type& interpolator() { return *m_interpolator; } const GradientF& gradient_function() const { return *m_gradient_function; } const ColorF color_function() const { return m_color_function; } double d1() const { return double(m_d1) / gradient_size; } double d2() const { return double(m_d2) / gradient_size; } //-------------------------------------------------------------------- void interpolator(interpolator_type& i) { m_interpolator = &i; } void gradient_function(const GradientF& gf) { m_gradient_function = &gf; } void color_function(ColorF cf) { m_color_function = cf; } void d1(double v) { m_d1 = int(v * gradient_size); } void d2(double v) { m_d2 = int(v * gradient_size); } //-------------------------------------------------------------------- color_type* generate(int x, int y, unsigned len) { color_type* span = base_type::allocator().span(); int dd = m_d2 - m_d1; if(dd < 1) dd = 1; m_interpolator->begin(x+0.5, y+0.5, len); do { m_interpolator->coordinates(&x, &y); int d = m_gradient_function->calculate(x >> downscale_shift, y >> downscale_shift, dd); d = ((d - m_d1) << base_shift) / dd; if(d < 0) d = 0; if(d > base_mask) d = base_mask; *span++ = m_color_function[d]; ++(*m_interpolator); } while(--len); return base_type::allocator().span(); } private: interpolator_type* m_interpolator; const GradientF* m_gradient_function; ColorF m_color_function; int m_d1; int m_d2; }; //=====================================================gradient_linear_color template struct gradient_linear_color { typedef ColorT color_type; enum { base_shift = BaseShift, base_size = 1 << base_shift, base_mask = base_size - 1 }; gradient_linear_color() {} gradient_linear_color(const color_type& c1, const color_type& c2) : m_c1(c1), m_c2(c2) {} color_type operator [] (unsigned v) const { return m_c1.gradient(m_c2, double(v) / double(base_mask)); } void colors(const color_type& c1, const color_type& c2) { m_c1 = c1; m_c2 = c2; } color_type m_c1; color_type m_c2; }; //---------------------------------------------------------gradient_circle class gradient_circle { public: static int calculate(int x, int y, int) { return int(fast_sqrt(x*x + y*y)); } }; //--------------------------------------------------------------gradient_x class gradient_x { public: static int calculate(int x, int, int) { return x; } }; //--------------------------------------------------------------gradient_y class gradient_y { public: static int calculate(int, int y, int) { return y; } }; //--------------------------------------------------------gradient_diamond class gradient_diamond { public: static int calculate(int x, int y, int) { int ax = abs(x); int ay = abs(y); return ax > ay ? ax : ay; } }; //-------------------------------------------------------------gradient_xy class gradient_xy { public: static int calculate(int x, int y, int d) { return abs(x) * abs(y) / d; } }; //--------------------------------------------------------gradient_sqrt_xy class gradient_sqrt_xy { public: static int calculate(int x, int y, int) { return fast_sqrt(abs(x) * abs(y)); } }; //----------------------------------------------------------gradient_conic class gradient_conic { public: static int calculate(int x, int y, int d) { return int(fabs(atan2(double(y), double(x))) * double(d) / pi); } }; } #endif aggdraw-1.3.14/agg2/include/agg_span_image_filter.h000066400000000000000000000063531417726601400221350ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Image transformations with filtering. Span generator base class // //---------------------------------------------------------------------------- #ifndef AGG_SPAN_IMAGE_FILTER_INCLUDED #define AGG_SPAN_IMAGE_FILTER_INCLUDED #include "agg_basics.h" #include "agg_image_filters.h" #include "agg_rendering_buffer.h" #include "agg_span_generator.h" namespace agg { //--------------------------------------------------span_image_filter template class span_image_filter : public span_generator { public: typedef ColorT color_type; typedef Allocator alloc_type; typedef Interpolator interpolator_type; //---------------------------------------------------------------- span_image_filter(alloc_type& alloc) : span_generator(alloc) {} //---------------------------------------------------------------- span_image_filter(alloc_type& alloc, const rendering_buffer& src, const color_type& back_color, interpolator_type& interpolator, const image_filter_base* filter) : span_generator(alloc), m_src(&src), m_back_color(back_color), m_interpolator(&interpolator), m_filter(filter) {} //---------------------------------------------------------------- const rendering_buffer& source_image() const { return *m_src; } const color_type& background_color() const { return m_back_color; } const image_filter_base& filter() const { return *m_filter; } //---------------------------------------------------------------- void source_image(const rendering_buffer& v) { m_src = &v; } void background_color(const color_type& v) { m_back_color = v; } void interpolator(interpolator_type& v) { m_interpolator = &v; } void filter(const image_filter_base& v) { m_filter = &v; } //---------------------------------------------------------------- interpolator_type& interpolator() { return *m_interpolator; } //---------------------------------------------------------------- private: const rendering_buffer* m_src; color_type m_back_color; interpolator_type* m_interpolator; const image_filter_base* m_filter; }; } #endif aggdraw-1.3.14/agg2/include/agg_span_image_filter_rgb24.h000066400000000000000000000502311417726601400231270ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_SPAN_IMAGE_FILTER_RGB24_INCLUDED #define AGG_SPAN_IMAGE_FILTER_RGB24_INCLUDED #include "agg_basics.h" #include "agg_color_rgba8.h" #include "agg_span_image_filter.h" namespace agg { //==============================================span_image_filter_rgb24_nn template > class span_image_filter_rgb24_nn : public span_image_filter { public: typedef Interpolator interpolator_type; typedef Allocator alloc_type; typedef span_image_filter base_type; typedef rgba8 color_type; //-------------------------------------------------------------------- span_image_filter_rgb24_nn(alloc_type& alloc) : base_type(alloc) {} //-------------------------------------------------------------------- span_image_filter_rgb24_nn(alloc_type& alloc, const rendering_buffer& src, const color_type& back_color, interpolator_type& inter) : base_type(alloc, src, back_color, inter, 0) {} //-------------------------------------------------------------------- color_type* generate(int x, int y, unsigned len) { base_type::interpolator().begin(x, y, len); int fg[3]; int src_alpha; const unsigned char *fg_ptr; color_type* span = base_type::allocator().span(); int maxx = base_type::source_image().width() - 1; int maxy = base_type::source_image().height() - 1; do { base_type::interpolator().coordinates(&x, &y); x >>= image_subpixel_shift; y >>= image_subpixel_shift; if(x >= 0 && y >= 0 && x <= maxx && y <= maxy) { fg_ptr = base_type::source_image().row(y) + x + x + x; fg[0] = *fg_ptr++; fg[1] = *fg_ptr++; fg[2] = *fg_ptr++; src_alpha = 255; } else { fg[Order::R] = base_type::background_color().r; fg[Order::G] = base_type::background_color().g; fg[Order::B] = base_type::background_color().b; src_alpha = base_type::background_color().a; } span->r = (int8u)fg[Order::R]; span->g = (int8u)fg[Order::G]; span->b = (int8u)fg[Order::B]; span->a = (int8u)src_alpha; ++span; ++base_type::interpolator(); } while(--len); return base_type::allocator().span(); } }; //=========================================span_image_filter_rgb24_bilinear template > class span_image_filter_rgb24_bilinear : public span_image_filter { public: typedef Interpolator interpolator_type; typedef Allocator alloc_type; typedef span_image_filter base_type; typedef rgba8 color_type; //-------------------------------------------------------------------- span_image_filter_rgb24_bilinear(alloc_type& alloc) : base_type(alloc) {} //-------------------------------------------------------------------- span_image_filter_rgb24_bilinear(alloc_type& alloc, const rendering_buffer& src, const color_type& back_color, interpolator_type& inter) : base_type(alloc, src, back_color, inter, 0) {} //-------------------------------------------------------------------- color_type* generate(int x, int y, unsigned len) { base_type::interpolator().begin(x, y, len); int fg[3]; int src_alpha; int back_r = base_type::background_color().r; int back_g = base_type::background_color().g; int back_b = base_type::background_color().b; int back_a = base_type::background_color().a; const unsigned char *fg_ptr; int stride = base_type::source_image().stride() - 2 * 3; color_type* span = base_type::allocator().span(); int maxx = base_type::source_image().width() - 1; int maxy = base_type::source_image().height() - 1; do { int x_hr; int y_hr; base_type::interpolator().coordinates(&x_hr, &y_hr); int x_lr = x_hr >> image_subpixel_shift; int y_lr = y_hr >> image_subpixel_shift; int weight; if(x_lr >= 0 && y_lr >= 0 && x_lr < maxx && y_lr < maxy) { fg[0] = fg[1] = fg[2] = image_subpixel_size * image_subpixel_size / 2; x_hr &= image_subpixel_mask; y_hr &= image_subpixel_mask; fg_ptr = base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr; weight = (image_subpixel_size - x_hr) * (image_subpixel_size - y_hr); fg[0] += weight * *fg_ptr++; fg[1] += weight * *fg_ptr++; fg[2] += weight * *fg_ptr++; weight = x_hr * (image_subpixel_size - y_hr); fg[0] += weight * *fg_ptr++; fg[1] += weight * *fg_ptr++; fg[2] += weight * *fg_ptr++; fg_ptr += stride; weight = (image_subpixel_size - x_hr) * y_hr; fg[0] += weight * *fg_ptr++; fg[1] += weight * *fg_ptr++; fg[2] += weight * *fg_ptr++; weight = x_hr * y_hr; fg[0] += weight * *fg_ptr++; fg[1] += weight * *fg_ptr++; fg[2] += weight * *fg_ptr++; fg[0] >>= image_subpixel_shift * 2; fg[1] >>= image_subpixel_shift * 2; fg[2] >>= image_subpixel_shift * 2; src_alpha = 255; } else { if(x_lr < -1 || y_lr < -1 || x_lr > maxx || y_lr > maxy) { fg[Order::R] = back_r; fg[Order::G] = back_g; fg[Order::B] = back_b; src_alpha = back_a; } else { fg[0] = fg[1] = fg[2] = src_alpha = image_subpixel_size * image_subpixel_size / 2; x_hr &= image_subpixel_mask; y_hr &= image_subpixel_mask; weight = (image_subpixel_size - x_hr) * (image_subpixel_size - y_hr); if(x_lr >= 0 && y_lr >= 0 && x_lr <= maxx && y_lr <= maxy) { fg_ptr = base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr; fg[0] += weight * *fg_ptr++; fg[1] += weight * *fg_ptr++; fg[2] += weight * *fg_ptr++; src_alpha += weight * 255; } else { fg[Order::R] += back_r * weight; fg[Order::G] += back_g * weight; fg[Order::B] += back_b * weight; src_alpha += back_a * weight; } x_lr++; weight = x_hr * (image_subpixel_size - y_hr); if(x_lr >= 0 && y_lr >= 0 && x_lr <= maxx && y_lr <= maxy) { fg_ptr = base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr; fg[0] += weight * *fg_ptr++; fg[1] += weight * *fg_ptr++; fg[2] += weight * *fg_ptr++; src_alpha += weight * 255; } else { fg[Order::R] += back_r * weight; fg[Order::G] += back_g * weight; fg[Order::B] += back_b * weight; src_alpha += back_a * weight; } x_lr--; y_lr++; weight = (image_subpixel_size - x_hr) * y_hr; if(x_lr >= 0 && y_lr >= 0 && x_lr <= maxx && y_lr <= maxy) { fg_ptr = base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr; fg[0] += weight * *fg_ptr++; fg[1] += weight * *fg_ptr++; fg[2] += weight * *fg_ptr++; src_alpha += weight * 255; } else { fg[Order::R] += back_r * weight; fg[Order::G] += back_g * weight; fg[Order::B] += back_b * weight; src_alpha += back_a * weight; } x_lr++; weight = x_hr * y_hr; if(x_lr >= 0 && y_lr >= 0 && x_lr <= maxx && y_lr <= maxy) { fg_ptr = base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr; fg[0] += weight * *fg_ptr++; fg[1] += weight * *fg_ptr++; fg[2] += weight * *fg_ptr++; src_alpha += weight * 255; } else { fg[Order::R] += back_r * weight; fg[Order::G] += back_g * weight; fg[Order::B] += back_b * weight; src_alpha += back_a * weight; } fg[0] >>= image_subpixel_shift * 2; fg[1] >>= image_subpixel_shift * 2; fg[2] >>= image_subpixel_shift * 2; src_alpha >>= image_subpixel_shift * 2; } } span->r = (int8u)fg[Order::R]; span->g = (int8u)fg[Order::G]; span->b = (int8u)fg[Order::B]; span->a = (int8u)src_alpha; ++span; ++base_type::interpolator(); } while(--len); return base_type::allocator().span(); } }; //=================================================span_image_filter_rgb24 template > class span_image_filter_rgb24 : public span_image_filter { public: typedef Interpolator interpolator_type; typedef Allocator alloc_type; typedef span_image_filter base_type; typedef rgba8 color_type; //-------------------------------------------------------------------- span_image_filter_rgb24(alloc_type& alloc) : base_type(alloc) {} //-------------------------------------------------------------------- span_image_filter_rgb24(alloc_type& alloc, const rendering_buffer& src, const color_type& back_color, interpolator_type& inter, const image_filter_base& filter) : base_type(alloc, src, back_color, inter, &filter) {} //-------------------------------------------------------------------- color_type* generate(int x, int y, unsigned len) { base_type::interpolator().begin(x, y, len); int fg[3]; int src_alpha; int back_r = base_type::background_color().r; int back_g = base_type::background_color().g; int back_b = base_type::background_color().b; int back_a = base_type::background_color().a; const unsigned char *fg_ptr; unsigned dimension = base_type::filter().dimension(); int start = base_type::filter().start(); int start1 = start - 1; const int* weight_array = base_type::filter().weight_array_int(); int stride = base_type::source_image().stride() - dimension * 3; color_type* span = base_type::allocator().span(); int maxx = base_type::source_image().width() + start - 2; int maxy = base_type::source_image().height() + start - 2; int maxx2 = base_type::source_image().width() - start - 1; int maxy2 = base_type::source_image().height() - start - 1; int x_count; int weight_y; do { base_type::interpolator().coordinates(&x, &y); int x_hr = x; int y_hr = y; int x_lr = x_hr >> image_subpixel_shift; int y_lr = y_hr >> image_subpixel_shift; fg[0] = fg[1] = fg[2] = image_filter_size / 2; int x_fract = x_hr & image_subpixel_mask; unsigned y_count = dimension; if(x_lr >= -start && y_lr >= -start && x_lr <= maxx && y_lr <= maxy) { y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask); fg_ptr = base_type::source_image().row(y_lr + start) + (x_lr + start) * 3; do { x_count = dimension; weight_y = weight_array[y_hr]; x_hr = image_subpixel_mask - x_fract; do { int weight = (weight_y * weight_array[x_hr] + image_filter_size / 2) >> image_filter_shift; fg[0] += *fg_ptr++ * weight; fg[1] += *fg_ptr++ * weight; fg[2] += *fg_ptr++ * weight; x_hr += image_subpixel_size; } while(--x_count); y_hr += image_subpixel_size; fg_ptr += stride; } while(--y_count); fg[0] >>= image_filter_shift; fg[1] >>= image_filter_shift; fg[2] >>= image_filter_shift; if(fg[0] < 0) fg[0] = 0; if(fg[1] < 0) fg[1] = 0; if(fg[2] < 0) fg[2] = 0; if(fg[0] > 255) fg[0] = 255; if(fg[1] > 255) fg[1] = 255; if(fg[2] > 255) fg[2] = 255; src_alpha = 255; } else { if(x_lr < start1 || y_lr < start1 || x_lr > maxx2 || y_lr > maxy2) { fg[Order::R] = back_r; fg[Order::G] = back_g; fg[Order::B] = back_b; src_alpha = back_a; } else { src_alpha = image_filter_size / 2; y_lr = (y >> image_subpixel_shift) + start; y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask); do { x_count = dimension; weight_y = weight_array[y_hr]; x_lr = (x >> image_subpixel_shift) + start; x_hr = image_subpixel_mask - x_fract; do { int weight = (weight_y * weight_array[x_hr] + image_filter_size / 2) >> image_filter_shift; if(x_lr >= 0 && y_lr >= 0 && x_lr < int(base_type::source_image().width()) && y_lr < int(base_type::source_image().height())) { fg_ptr = base_type::source_image().row(y_lr) + x_lr * 3; fg[0] += *fg_ptr++ * weight; fg[1] += *fg_ptr++ * weight; fg[2] += *fg_ptr++ * weight; src_alpha += 255 * weight; } else { fg[Order::R] += back_r * weight; fg[Order::G] += back_g * weight; fg[Order::B] += back_b * weight; src_alpha += back_a * weight; } x_hr += image_subpixel_size; x_lr++; } while(--x_count); y_hr += image_subpixel_size; y_lr++; } while(--y_count); fg[0] >>= image_filter_shift; fg[1] >>= image_filter_shift; fg[2] >>= image_filter_shift; src_alpha >>= image_filter_shift; if(fg[0] < 0) fg[0] = 0; if(fg[1] < 0) fg[1] = 0; if(fg[2] < 0) fg[2] = 0; if(src_alpha < 0) src_alpha = 0; if(fg[0] > 255) fg[0] = 255; if(fg[1] > 255) fg[1] = 255; if(fg[2] > 255) fg[2] = 255; if(src_alpha > 255) src_alpha = 255; } } span->r = (int8u)fg[Order::R]; span->g = (int8u)fg[Order::G]; span->b = (int8u)fg[Order::B]; span->a = (int8u)src_alpha; ++span; ++base_type::interpolator(); } while(--len); return base_type::allocator().span(); } }; } #endif aggdraw-1.3.14/agg2/include/agg_span_image_filter_rgb24_gamma.h000066400000000000000000000454141417726601400243000ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_SPAN_IMAGE_FILTER_RGB24_GAMMA_INCLUDED #define AGG_SPAN_IMAGE_FILTER_RGB24_GAMMA_INCLUDED #include "agg_basics.h" #include "agg_color_rgba8.h" #include "agg_span_image_filter.h" #include "agg_gamma_lut.h" namespace agg { //===================================span_image_filter_rgb24_gamma_bilinear template, class Gamma = gamma_lut > class span_image_filter_rgb24_gamma_bilinear : public span_image_filter { public: typedef Interpolator interpolator_type; typedef Allocator alloc_type; typedef span_image_filter base_type; typedef rgba8 color_type; typedef Gamma gamma_type; //-------------------------------------------------------------------- span_image_filter_rgb24_gamma_bilinear(alloc_type& alloc, const gamma_type& g) : base_type(alloc), m_gamma(&g) {} //-------------------------------------------------------------------- span_image_filter_rgb24_gamma_bilinear(alloc_type& alloc, const rendering_buffer& src, const color_type& back_color, interpolator_type& inter, const gamma_type& g) : base_type(alloc, src, back_color, inter, 0), m_gamma(&g) {} //-------------------------------------------------------------------- color_type* generate(int x, int y, unsigned len) { base_type::interpolator().begin(x, y, len); int fg[3]; int src_alpha; int back_r = m_gamma->dir(base_type::background_color().r); int back_g = m_gamma->dir(base_type::background_color().g); int back_b = m_gamma->dir(base_type::background_color().b); int back_a = base_type::background_color().a; const unsigned char *fg_ptr; int stride = base_type::source_image().stride() - 2 * 3; color_type* span = base_type::allocator().span(); int maxx = base_type::source_image().width() - 1; int maxy = base_type::source_image().height() - 1; do { int x_hr; int y_hr; base_type::interpolator().coordinates(&x_hr, &y_hr); int x_lr = x_hr >> image_subpixel_shift; int y_lr = y_hr >> image_subpixel_shift; int weight; if(x_lr >= 0 && y_lr >= 0 && x_lr < maxx && y_lr < maxy) { fg[0] = fg[1] = fg[2] = image_subpixel_size * image_subpixel_size / 2; x_hr &= image_subpixel_mask; y_hr &= image_subpixel_mask; fg_ptr = base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr; weight = (image_subpixel_size - x_hr) * (image_subpixel_size - y_hr); fg[0] += weight * m_gamma->dir(*fg_ptr++); fg[1] += weight * m_gamma->dir(*fg_ptr++); fg[2] += weight * m_gamma->dir(*fg_ptr++); weight = x_hr * (image_subpixel_size - y_hr); fg[0] += weight * m_gamma->dir(*fg_ptr++); fg[1] += weight * m_gamma->dir(*fg_ptr++); fg[2] += weight * m_gamma->dir(*fg_ptr++); fg_ptr += stride; weight = (image_subpixel_size - x_hr) * y_hr; fg[0] += weight * m_gamma->dir(*fg_ptr++); fg[1] += weight * m_gamma->dir(*fg_ptr++); fg[2] += weight * m_gamma->dir(*fg_ptr++); weight = x_hr * y_hr; fg[0] += weight * m_gamma->dir(*fg_ptr++); fg[1] += weight * m_gamma->dir(*fg_ptr++); fg[2] += weight * m_gamma->dir(*fg_ptr++); fg[0] >>= image_subpixel_shift * 2; fg[1] >>= image_subpixel_shift * 2; fg[2] >>= image_subpixel_shift * 2; src_alpha = 255; } else { if(x_lr < -1 || y_lr < -1 || x_lr > maxx || y_lr > maxy) { fg[Order::R] = back_r; fg[Order::G] = back_g; fg[Order::B] = back_b; src_alpha = back_a; } else { fg[0] = fg[1] = fg[2] = src_alpha = image_subpixel_size * image_subpixel_size / 2; x_hr &= image_subpixel_mask; y_hr &= image_subpixel_mask; weight = (image_subpixel_size - x_hr) * (image_subpixel_size - y_hr); if(x_lr >= 0 && y_lr >= 0 && x_lr <= maxx && y_lr <= maxy) { fg_ptr = base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr; fg[0] += weight * m_gamma->dir(*fg_ptr++); fg[1] += weight * m_gamma->dir(*fg_ptr++); fg[2] += weight * m_gamma->dir(*fg_ptr++); src_alpha += weight * 255; } else { fg[Order::R] += back_r * weight; fg[Order::G] += back_g * weight; fg[Order::B] += back_b * weight; src_alpha += back_a * weight; } x_lr++; weight = x_hr * (image_subpixel_size - y_hr); if(x_lr >= 0 && y_lr >= 0 && x_lr <= maxx && y_lr <= maxy) { fg_ptr = base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr; fg[0] += weight * m_gamma->dir(*fg_ptr++); fg[1] += weight * m_gamma->dir(*fg_ptr++); fg[2] += weight * m_gamma->dir(*fg_ptr++); src_alpha += weight * 255; } else { fg[Order::R] += back_r * weight; fg[Order::G] += back_g * weight; fg[Order::B] += back_b * weight; src_alpha += back_a * weight; } x_lr--; y_lr++; weight = (image_subpixel_size - x_hr) * y_hr; if(x_lr >= 0 && y_lr >= 0 && x_lr <= maxx && y_lr <= maxy) { fg_ptr = base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr; fg[0] += weight * m_gamma->dir(*fg_ptr++); fg[1] += weight * m_gamma->dir(*fg_ptr++); fg[2] += weight * m_gamma->dir(*fg_ptr++); src_alpha += weight * 255; } else { fg[Order::R] += back_r * weight; fg[Order::G] += back_g * weight; fg[Order::B] += back_b * weight; src_alpha += back_a * weight; } x_lr++; weight = x_hr * y_hr; if(x_lr >= 0 && y_lr >= 0 && x_lr <= maxx && y_lr <= maxy) { fg_ptr = base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr; fg[0] += weight * m_gamma->dir(*fg_ptr++); fg[1] += weight * m_gamma->dir(*fg_ptr++); fg[2] += weight * m_gamma->dir(*fg_ptr++); src_alpha += weight * 255; } else { fg[Order::R] += back_r * weight; fg[Order::G] += back_g * weight; fg[Order::B] += back_b * weight; src_alpha += back_a * weight; } fg[0] >>= image_subpixel_shift * 2; fg[1] >>= image_subpixel_shift * 2; fg[2] >>= image_subpixel_shift * 2; src_alpha >>= image_subpixel_shift * 2; } } span->r = (int8u)m_gamma->inv(fg[Order::R]); span->g = (int8u)m_gamma->inv(fg[Order::G]); span->b = (int8u)m_gamma->inv(fg[Order::B]); span->a = (int8u)src_alpha; ++span; ++base_type::interpolator(); } while(--len); return base_type::allocator().span(); } private: const gamma_type* m_gamma; }; //============================================span_image_filter_rgb24_gamma template, class Gamma = gamma_lut > class span_image_filter_rgb24_gamma : public span_image_filter { public: typedef Interpolator interpolator_type; typedef Allocator alloc_type; typedef span_image_filter base_type; typedef rgba8 color_type; typedef Gamma gamma_type; //-------------------------------------------------------------------- span_image_filter_rgb24_gamma(alloc_type& alloc, const gamma_type& g) : base_type(alloc), m_gamma(&g) {} //-------------------------------------------------------------------- span_image_filter_rgb24_gamma(alloc_type& alloc, const rendering_buffer& src, const color_type& back_color, interpolator_type& inter, const image_filter_base& filter, const gamma_type& g) : base_type(alloc, src, back_color, inter, &filter), m_gamma(&g) {} //-------------------------------------------------------------------- color_type* generate(int x, int y, unsigned len) { base_type::interpolator().begin(x, y, len); int fg[3]; int src_alpha; int back_r = m_gamma->dir(base_type::background_color().r); int back_g = m_gamma->dir(base_type::background_color().g); int back_b = m_gamma->dir(base_type::background_color().b); int back_a = base_type::background_color().a; const unsigned char *fg_ptr; unsigned dimension = base_type::filter().dimension(); int start = base_type::filter().start(); int start1 = start - 1; const int* weight_array = base_type::filter().weight_array_int(); int stride = base_type::source_image().stride() - dimension * 3; color_type* span = base_type::allocator().span(); int maxx = base_type::source_image().width() + start - 2; int maxy = base_type::source_image().height() + start - 2; int maxx2 = base_type::source_image().width() - start - 1; int maxy2 = base_type::source_image().height() - start - 1; int x_count; int weight_y; do { base_type::interpolator().coordinates(&x, &y); int x_hr = x; int y_hr = y; int x_lr = x_hr >> image_subpixel_shift; int y_lr = y_hr >> image_subpixel_shift; fg[0] = fg[1] = fg[2] = image_filter_size / 2; int x_fract = x_hr & image_subpixel_mask; unsigned y_count = dimension; if(x_lr >= -start && y_lr >= -start && x_lr <= maxx && y_lr <= maxy) { y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask); fg_ptr = base_type::source_image().row(y_lr + start) + (x_lr + start) * 3; do { x_count = dimension; weight_y = weight_array[y_hr]; x_hr = image_subpixel_mask - x_fract; do { int weight = (weight_y * weight_array[x_hr] + image_filter_size / 2) >> image_filter_shift; fg[0] += m_gamma->dir(*fg_ptr++) * weight; fg[1] += m_gamma->dir(*fg_ptr++) * weight; fg[2] += m_gamma->dir(*fg_ptr++) * weight; x_hr += image_subpixel_size; } while(--x_count); y_hr += image_subpixel_size; fg_ptr += stride; } while(--y_count); fg[0] >>= image_filter_shift; fg[1] >>= image_filter_shift; fg[2] >>= image_filter_shift; if(fg[0] < 0) fg[0] = 0; if(fg[1] < 0) fg[1] = 0; if(fg[2] < 0) fg[2] = 0; if(fg[0] > 255) fg[0] = 255; if(fg[1] > 255) fg[1] = 255; if(fg[2] > 255) fg[2] = 255; src_alpha = 255; } else { if(x_lr < start1 || y_lr < start1 || x_lr > maxx2 || y_lr > maxy2) { fg[Order::R] = back_r; fg[Order::G] = back_g; fg[Order::B] = back_b; src_alpha = back_a; } else { src_alpha = image_filter_size / 2; y_lr = (y >> image_subpixel_shift) + start; y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask); do { x_count = dimension; weight_y = weight_array[y_hr]; x_lr = (x >> image_subpixel_shift) + start; x_hr = image_subpixel_mask - x_fract; do { int weight = (weight_y * weight_array[x_hr] + image_filter_size / 2) >> image_filter_shift; if(x_lr >= 0 && y_lr >= 0 && x_lr < int(base_type::source_image().width()) && y_lr < int(base_type::source_image().height())) { fg_ptr = base_type::source_image().row(y_lr) + x_lr * 3; fg[0] += m_gamma->dir(*fg_ptr++) * weight; fg[1] += m_gamma->dir(*fg_ptr++) * weight; fg[2] += m_gamma->dir(*fg_ptr++) * weight; src_alpha += 255 * weight; } else { fg[Order::R] += back_r * weight; fg[Order::G] += back_g * weight; fg[Order::B] += back_b * weight; src_alpha += back_a * weight; } x_hr += image_subpixel_size; x_lr++; } while(--x_count); y_hr += image_subpixel_size; y_lr++; } while(--y_count); fg[0] >>= image_filter_shift; fg[1] >>= image_filter_shift; fg[2] >>= image_filter_shift; src_alpha >>= image_filter_shift; if(fg[0] < 0) fg[0] = 0; if(fg[1] < 0) fg[1] = 0; if(fg[2] < 0) fg[2] = 0; if(src_alpha < 0) src_alpha = 0; if(fg[0] > 255) fg[0] = 255; if(fg[1] > 255) fg[1] = 255; if(fg[2] > 255) fg[2] = 255; if(src_alpha > 255) src_alpha = 255; } } span->r = (int8u)m_gamma->inv(fg[Order::R]); span->g = (int8u)m_gamma->inv(fg[Order::G]); span->b = (int8u)m_gamma->inv(fg[Order::B]); span->a = (int8u)src_alpha; ++span; ++base_type::interpolator(); } while(--len); return base_type::allocator().span(); } private: const gamma_type* m_gamma; }; } #endif aggdraw-1.3.14/agg2/include/agg_span_image_filter_rgba32.h000066400000000000000000000507111417726601400232720ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // classes span_image_filter_rgba32* // //---------------------------------------------------------------------------- #ifndef AGG_SPAN_IMAGE_FILTER_RGBA32_INCLUDED #define AGG_SPAN_IMAGE_FILTER_RGBA32_INCLUDED #include "agg_basics.h" #include "agg_color_rgba8.h" #include "agg_span_image_filter.h" namespace agg { //=============================================span_image_filter_rgba32_nn template > class span_image_filter_rgba32_nn : public span_image_filter { public: typedef Interpolator interpolator_type; typedef Allocator alloc_type; typedef span_image_filter base_type; typedef rgba8 color_type; //-------------------------------------------------------------------- span_image_filter_rgba32_nn(alloc_type& alloc) : base_type(alloc) {} //-------------------------------------------------------------------- span_image_filter_rgba32_nn(alloc_type& alloc, const rendering_buffer& src, const color_type& back_color, interpolator_type& inter) : base_type(alloc, src, back_color, inter, 0) {} //-------------------------------------------------------------------- color_type* generate(int x, int y, unsigned len) { base_type::interpolator().begin(x, y, len); int fg[4]; const unsigned char *fg_ptr; color_type* span = base_type::allocator().span(); int maxx = base_type::source_image().width() - 1; int maxy = base_type::source_image().height() - 1; do { base_type::interpolator().coordinates(&x, &y); x >>= image_subpixel_shift; y >>= image_subpixel_shift; if(x >= 0 && y >= 0 && x <= maxx && y <= maxy) { fg_ptr = base_type::source_image().row(y) + (x << 2); fg[0] = *fg_ptr++; fg[1] = *fg_ptr++; fg[2] = *fg_ptr++; fg[3] = *fg_ptr++; } else { fg[Order::R] = base_type::background_color().r; fg[Order::G] = base_type::background_color().g; fg[Order::B] = base_type::background_color().b; fg[Order::A] = base_type::background_color().a; } span->r = fg[Order::R]; span->g = fg[Order::G]; span->b = fg[Order::B]; span->a = fg[Order::A]; ++span; ++base_type::interpolator(); } while(--len); return base_type::allocator().span(); } }; //=======================================span_image_filter_rgba32_bilinear template > class span_image_filter_rgba32_bilinear : public span_image_filter { public: typedef Interpolator interpolator_type; typedef Allocator alloc_type; typedef span_image_filter base_type; typedef rgba8 color_type; //-------------------------------------------------------------------- span_image_filter_rgba32_bilinear(alloc_type& alloc) : base_type(alloc) {} //-------------------------------------------------------------------- span_image_filter_rgba32_bilinear(alloc_type& alloc, const rendering_buffer& src, const color_type& back_color, interpolator_type& inter) : base_type(alloc, src, back_color, inter, 0) {} //-------------------------------------------------------------------- color_type* generate(int x, int y, unsigned len) { base_type::interpolator().begin(x, y, len); int fg[4]; int back_r = base_type::background_color().r; int back_g = base_type::background_color().g; int back_b = base_type::background_color().b; int back_a = base_type::background_color().a; const unsigned char *fg_ptr; int stride = base_type::source_image().stride() - 2 * 4; color_type* span = base_type::allocator().span(); int maxx = base_type::source_image().width() - 1; int maxy = base_type::source_image().height() - 1; do { int x_hr; int y_hr; base_type::interpolator().coordinates(&x_hr, &y_hr); int x_lr = x_hr >> image_subpixel_shift; int y_lr = y_hr >> image_subpixel_shift; int weight; if(x_lr >= 0 && y_lr >= 0 && x_lr < maxx && y_lr < maxy) { fg[0] = fg[1] = fg[2] = fg[3] = image_subpixel_size * image_subpixel_size / 2; x_hr &= image_subpixel_mask; y_hr &= image_subpixel_mask; fg_ptr = base_type::source_image().row(y_lr) + (x_lr << 2); weight = (image_subpixel_size - x_hr) * (image_subpixel_size - y_hr); fg[0] += weight * *fg_ptr++; fg[1] += weight * *fg_ptr++; fg[2] += weight * *fg_ptr++; fg[3] += weight * *fg_ptr++; weight = x_hr * (image_subpixel_size - y_hr); fg[0] += weight * *fg_ptr++; fg[1] += weight * *fg_ptr++; fg[2] += weight * *fg_ptr++; fg[3] += weight * *fg_ptr++; fg_ptr += stride; weight = (image_subpixel_size - x_hr) * y_hr; fg[0] += weight * *fg_ptr++; fg[1] += weight * *fg_ptr++; fg[2] += weight * *fg_ptr++; fg[3] += weight * *fg_ptr++; weight = x_hr * y_hr; fg[0] += weight * *fg_ptr++; fg[1] += weight * *fg_ptr++; fg[2] += weight * *fg_ptr++; fg[3] += weight * *fg_ptr++; fg[0] >>= image_subpixel_shift * 2; fg[1] >>= image_subpixel_shift * 2; fg[2] >>= image_subpixel_shift * 2; fg[3] >>= image_subpixel_shift * 2; } else { if(x_lr < -1 || y_lr < -1 || x_lr > maxx || y_lr > maxy) { fg[Order::R] = back_r; fg[Order::G] = back_g; fg[Order::B] = back_b; fg[Order::A] = back_a; } else { fg[0] = fg[1] = fg[2] = fg[3] = image_subpixel_size * image_subpixel_size / 2; x_hr &= image_subpixel_mask; y_hr &= image_subpixel_mask; weight = (image_subpixel_size - x_hr) * (image_subpixel_size - y_hr); if(x_lr >= 0 && y_lr >= 0 && x_lr <= maxx && y_lr <= maxy) { fg_ptr = base_type::source_image().row(y_lr) + (x_lr << 2); fg[0] += weight * *fg_ptr++; fg[1] += weight * *fg_ptr++; fg[2] += weight * *fg_ptr++; fg[3] += weight * *fg_ptr++; } else { fg[Order::R] += back_r * weight; fg[Order::G] += back_g * weight; fg[Order::B] += back_b * weight; fg[Order::A] += back_a * weight; } x_lr++; weight = x_hr * (image_subpixel_size - y_hr); if(x_lr >= 0 && y_lr >= 0 && x_lr <= maxx && y_lr <= maxy) { fg_ptr = base_type::source_image().row(y_lr) + (x_lr << 2); fg[0] += weight * *fg_ptr++; fg[1] += weight * *fg_ptr++; fg[2] += weight * *fg_ptr++; fg[3] += weight * *fg_ptr++; } else { fg[Order::R] += back_r * weight; fg[Order::G] += back_g * weight; fg[Order::B] += back_b * weight; fg[Order::A] += back_a * weight; } x_lr--; y_lr++; weight = (image_subpixel_size - x_hr) * y_hr; if(x_lr >= 0 && y_lr >= 0 && x_lr <= maxx && y_lr <= maxy) { fg_ptr = base_type::source_image().row(y_lr) + (x_lr << 2); fg[0] += weight * *fg_ptr++; fg[1] += weight * *fg_ptr++; fg[2] += weight * *fg_ptr++; fg[3] += weight * *fg_ptr++; } else { fg[Order::R] += back_r * weight; fg[Order::G] += back_g * weight; fg[Order::B] += back_b * weight; fg[Order::A] += back_a * weight; } x_lr++; weight = x_hr * y_hr; if(x_lr >= 0 && y_lr >= 0 && x_lr <= maxx && y_lr <= maxy) { fg_ptr = base_type::source_image().row(y_lr) + (x_lr << 2); fg[0] += weight * *fg_ptr++; fg[1] += weight * *fg_ptr++; fg[2] += weight * *fg_ptr++; fg[3] += weight * *fg_ptr++; } else { fg[Order::R] += back_r * weight; fg[Order::G] += back_g * weight; fg[Order::B] += back_b * weight; fg[Order::A] += back_a * weight; } fg[0] >>= image_subpixel_shift * 2; fg[1] >>= image_subpixel_shift * 2; fg[2] >>= image_subpixel_shift * 2; fg[3] >>= image_subpixel_shift * 2; } } span->r = (int8u)fg[Order::R]; span->g = (int8u)fg[Order::G]; span->b = (int8u)fg[Order::B]; span->a = (int8u)fg[Order::A]; ++span; ++base_type::interpolator(); } while(--len); return base_type::allocator().span(); } }; //================================================span_image_filter_rgba32 template > class span_image_filter_rgba32 : public span_image_filter { public: typedef Interpolator interpolator_type; typedef Allocator alloc_type; typedef span_image_filter base_type; typedef rgba8 color_type; //-------------------------------------------------------------------- span_image_filter_rgba32(alloc_type& alloc) : base_type(alloc) {} //-------------------------------------------------------------------- span_image_filter_rgba32(alloc_type& alloc, const rendering_buffer& src, const color_type& back_color, interpolator_type& inter, const image_filter_base& filter) : base_type(alloc, src, back_color, inter, &filter) {} //-------------------------------------------------------------------- color_type* generate(int x, int y, unsigned len) { base_type::interpolator().begin(x, y, len); int fg[4]; int back_r = base_type::background_color().r; int back_g = base_type::background_color().g; int back_b = base_type::background_color().b; int back_a = base_type::background_color().a; const unsigned char *fg_ptr; unsigned dimension = base_type::filter().dimension(); int start = base_type::filter().start(); int start1 = start - 1; const int* weight_array = base_type::filter().weight_array_int(); int stride = base_type::source_image().stride() - (dimension << 2); color_type* span = base_type::allocator().span(); int maxx = base_type::source_image().width() + start - 2; int maxy = base_type::source_image().height() + start - 2; int maxx2 = base_type::source_image().width() - start - 1; int maxy2 = base_type::source_image().height() - start - 1; int x_count; int weight_y; do { base_type::interpolator().coordinates(&x, &y); int x_hr = x; int y_hr = y; int x_lr = x_hr >> image_subpixel_shift; int y_lr = y_hr >> image_subpixel_shift; fg[0] = fg[1] = fg[2] = fg[3] = image_filter_size / 2; int x_fract = x_hr & image_subpixel_mask; unsigned y_count = dimension; if(x_lr >= -start && y_lr >= -start && x_lr <= maxx && y_lr <= maxy) { y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask); fg_ptr = base_type::source_image().row(y_lr + start) + ((x_lr + start) << 2); do { x_count = dimension; weight_y = weight_array[y_hr]; x_hr = image_subpixel_mask - x_fract; do { int weight = (weight_y * weight_array[x_hr] + image_filter_size / 2) >> image_filter_shift; fg[0] += *fg_ptr++ * weight; fg[1] += *fg_ptr++ * weight; fg[2] += *fg_ptr++ * weight; fg[3] += *fg_ptr++ * weight; x_hr += image_subpixel_size; } while(--x_count); y_hr += image_subpixel_size; fg_ptr += stride; } while(--y_count); fg[0] >>= image_filter_shift; fg[1] >>= image_filter_shift; fg[2] >>= image_filter_shift; fg[3] >>= image_filter_shift; if(fg[0] < 0) fg[0] = 0; if(fg[1] < 0) fg[1] = 0; if(fg[2] < 0) fg[2] = 0; if(fg[3] < 0) fg[3] = 0; if(fg[0] > 255) fg[0] = 255; if(fg[1] > 255) fg[1] = 255; if(fg[2] > 255) fg[2] = 255; if(fg[3] > 255) fg[3] = 255; } else { if(x_lr < start1 || y_lr < start1 || x_lr > maxx2 || y_lr > maxy2) { fg[Order::R] = back_r; fg[Order::G] = back_g; fg[Order::B] = back_b; fg[Order::A] = back_a; } else { y_lr = (y >> image_subpixel_shift) + start; y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask); do { x_count = dimension; weight_y = weight_array[y_hr]; x_lr = (x >> image_subpixel_shift) + start; x_hr = image_subpixel_mask - x_fract; do { int weight = (weight_y * weight_array[x_hr] + image_filter_size / 2) >> image_filter_shift; if(x_lr >= 0 && y_lr >= 0 && x_lr < int(base_type::source_image().width()) && y_lr < int(base_type::source_image().height())) { fg_ptr = base_type::source_image().row(y_lr) + (x_lr << 2); fg[0] += *fg_ptr++ * weight; fg[1] += *fg_ptr++ * weight; fg[2] += *fg_ptr++ * weight; fg[3] += *fg_ptr++ * weight; } else { fg[Order::R] += back_r * weight; fg[Order::G] += back_g * weight; fg[Order::B] += back_b * weight; fg[Order::A] += back_a * weight; } x_hr += image_subpixel_size; x_lr++; } while(--x_count); y_hr += image_subpixel_size; y_lr++; } while(--y_count); fg[0] >>= image_filter_shift; fg[1] >>= image_filter_shift; fg[2] >>= image_filter_shift; fg[3] >>= image_filter_shift; if(fg[0] < 0) fg[0] = 0; if(fg[1] < 0) fg[1] = 0; if(fg[2] < 0) fg[2] = 0; if(fg[3] < 0) fg[3] = 0; if(fg[0] > 255) fg[0] = 255; if(fg[1] > 255) fg[1] = 255; if(fg[2] > 255) fg[2] = 255; if(fg[3] > 255) fg[3] = 255; } } span->r = fg[Order::R]; span->g = fg[Order::G]; span->b = fg[Order::B]; span->a = fg[Order::A]; ++span; ++base_type::interpolator(); } while(--len); return base_type::allocator().span(); } }; } #endif aggdraw-1.3.14/agg2/include/agg_span_interpolator_adaptor.h000066400000000000000000000051521417726601400237360ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_SPAN_INTERPOLATOR_ADAPTOR_INCLUDED #define AGG_SPAN_INTERPOLATOR_ADAPTOR_INCLUDED #include "agg_basics.h" namespace agg { //===============================================span_interpolator_adaptor template class span_interpolator_adaptor : public Interpolator { public: typedef Interpolator base_type; typedef typename base_type::trans_type trans_type; typedef Distortion distortion_type; //-------------------------------------------------------------------- span_interpolator_adaptor() {} span_interpolator_adaptor(const trans_type& trans, const distortion_type& dist) : base_type(trans), m_distortion(&dist) { } //-------------------------------------------------------------------- span_interpolator_adaptor(const trans_type& trans, const distortion_type& dist, double x, double y, unsigned len) : base_type(trans, x, y, len), m_distortion(&dist) { } //-------------------------------------------------------------------- const distortion_type& distortion() const { return *m_distortion; } //-------------------------------------------------------------------- void distortion(const distortion_type& dist) { m_distortion = dist; } //-------------------------------------------------------------------- void coordinates(int* x, int* y) const { base_type::coordinates(x, y); m_distortion->calculate(x, y); } private: //-------------------------------------------------------------------- const distortion_type* m_distortion; }; } #endif aggdraw-1.3.14/agg2/include/agg_span_interpolator_linear.h000066400000000000000000000060301417726601400235520ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_SPAN_INTERPOLATOR_LINEAR_INCLUDED #define AGG_SPAN_INTERPOLATOR_LINEAR_INCLUDED #include "agg_basics.h" #include "agg_dda_line.h" #include "agg_trans_affine.h" namespace agg { //================================================span_interpolator_linear template class span_interpolator_linear { public: typedef Transformer trans_type; enum { subpixel_shift = SubpixelShift, subpixel_size = 1 << subpixel_shift }; //-------------------------------------------------------------------- span_interpolator_linear() {} span_interpolator_linear(const trans_type& trans) : m_trans(&trans) {} span_interpolator_linear(const trans_type& trans, double x, double y, unsigned len) : m_trans(&trans) { begin(x, y, len); } //---------------------------------------------------------------- const trans_type& transformer() const { return *m_trans; } void transformer(const trans_type& trans) { m_trans = &trans; } //---------------------------------------------------------------- void begin(double x, double y, unsigned len) { double tx; double ty; tx = x; ty = y; m_trans->transform(&tx, &ty); int x1 = int(tx * subpixel_size); int y1 = int(ty * subpixel_size); tx = x + len; ty = y; m_trans->transform(&tx, &ty); int x2 = int(tx * subpixel_size); int y2 = int(ty * subpixel_size); m_li_x = dda2_line_interpolator(x1, x2, len); m_li_y = dda2_line_interpolator(y1, y2, len); } //---------------------------------------------------------------- void operator++() { ++m_li_x; ++m_li_y; } //---------------------------------------------------------------- void coordinates(int* x, int* y) const { *x = m_li_x.y(); *y = m_li_y.y(); } private: const trans_type* m_trans; dda2_line_interpolator m_li_x; dda2_line_interpolator m_li_y; }; } #endif aggdraw-1.3.14/agg2/include/agg_span_interpolator_trans.h000066400000000000000000000060751417726601400234400ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Horizontal span interpolator for use with an arbitrary transformer // The efficiency highly depends on the operations done in the transformer // //---------------------------------------------------------------------------- #ifndef AGG_SPAN_INTERPOLATOR_TRANS_INCLUDED #define AGG_SPAN_INTERPOLATOR_TRANS_INCLUDED #include "agg_basics.h" namespace agg { //=================================================span_interpolator_trans template class span_interpolator_trans { public: typedef Transformer trans_type; enum { subpixel_shift = SubpixelShift, subpixel_size = 1 << subpixel_shift }; //-------------------------------------------------------------------- span_interpolator_trans() {} span_interpolator_trans(const trans_type& trans) : m_trans(&trans) {} span_interpolator_trans(const trans_type& trans, double x, double y, unsigned) : m_trans(&trans) { begin(x, y, 0); } //---------------------------------------------------------------- const trans_type& transformer() const { return *m_trans; } void transformer(const trans_type& trans) { m_trans = &trans; } //---------------------------------------------------------------- void begin(double x, double y, unsigned) { m_x = x; m_y = y; transform(); } //---------------------------------------------------------------- void operator++() { m_x += 1.0; transform(); } //---------------------------------------------------------------- void coordinates(int* x, int* y) const { *x = m_ix; *y = m_iy; } private: //---------------------------------------------------------------- void transform() { double x = m_x; double y = m_y; m_trans->transform(&x, &y); m_ix = int(x * subpixel_size); m_iy = int(y * subpixel_size); } const trans_type* m_trans; double m_x; double m_y; int m_ix; int m_iy; }; } #endif aggdraw-1.3.14/agg2/include/agg_span_pattern.h000066400000000000000000000053501417726601400211570ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_SPAN_PATTERN_INCLUDED #define AGG_SPAN_PATTERN_INCLUDED #include "agg_basics.h" #include "agg_rendering_buffer.h" #include "agg_span_generator.h" namespace agg { //--------------------------------------------------------span_pattern template class span_pattern : public span_generator { public: typedef ColorT color_type; typedef AlphaT alpha_type; typedef Allocator alloc_type; //---------------------------------------------------------------- span_pattern(alloc_type& alloc) : span_generator(alloc) {} //---------------------------------------------------------------- span_pattern(alloc_type& alloc, const rendering_buffer& src, unsigned offset_x, unsigned offset_y, alpha_type alpha) : span_generator(alloc), m_src(&src), m_offset_x(offset_x), m_offset_y(offset_y), m_alpha(alpha) {} //---------------------------------------------------------------- const rendering_buffer& source_image() const { return *m_src; } unsigned offset_x() const { return m_offset_x; } unsigned offset_y() const { return m_offset_y; } alpha_type alpha() const { return m_alpha; } //---------------------------------------------------------------- void source_image(const rendering_buffer& v) { m_src = &v; } void offset_x(unsigned v) { m_offset_x = v; } void offset_y(unsigned v) { m_offset_y = v; } void alpha(alpha_type v) { m_alpha = v; } //---------------------------------------------------------------- private: const rendering_buffer* m_src; unsigned m_offset_x; unsigned m_offset_y; alpha_type m_alpha; }; } #endif aggdraw-1.3.14/agg2/include/agg_span_pattern_rgb24.h000066400000000000000000000055211417726601400221570ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_SPAN_PATTERN_RGB24_INCLUDED #define AGG_SPAN_PATTERN_RGB24_INCLUDED #include "agg_basics.h" #include "agg_pixfmt_rgb24.h" #include "agg_span_pattern.h" namespace agg { //=======================================================span_pattern_rgb24 template > class span_pattern_rgb24 : public span_pattern { public: typedef Allocator alloc_type; typedef rgba8 color_type; typedef span_pattern base_type; //-------------------------------------------------------------------- span_pattern_rgb24(alloc_type& alloc) : base_type(alloc) {} //---------------------------------------------------------------- span_pattern_rgb24(alloc_type& alloc, const rendering_buffer& src, unsigned offset_x, unsigned offset_y, int8u alpha = 255) : base_type(alloc, src, offset_x, offset_y, alpha) {} //-------------------------------------------------------------------- color_type* generate(int x, int y, unsigned len) { color_type* span = base_type::allocator().span(); unsigned sx = (base_type::offset_x() + x) % base_type::source_image().width(); unsigned wp = base_type::source_image().width() * 3; const int8u* p = base_type::source_image().row((base_type::offset_y() + y) % base_type::source_image().height()); p += sx * 3; do { span->r = p[Order::R]; span->g = p[Order::G]; span->b = p[Order::B]; span->a = base_type::alpha(); p += 3; ++sx; ++span; if(sx >= base_type::source_image().width()) { sx -= base_type::source_image().width(); p -= wp; } } while(--len); return base_type::allocator().span(); } }; } #endif aggdraw-1.3.14/agg2/include/agg_span_pattern_rgba32.h000066400000000000000000000054401417726601400223170ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_SPAN_PATTERN_RGBA32_INCLUDED #define AGG_SPAN_PATTERN_RGBA32_INCLUDED #include "agg_basics.h" #include "agg_pixfmt_rgba32.h" #include "agg_span_pattern.h" namespace agg { //======================================================span_pattern_rgba32 template > class span_pattern_rgba32 : public span_pattern { public: typedef Allocator alloc_type; typedef rgba8 color_type; typedef span_pattern base_type; //-------------------------------------------------------------------- span_pattern_rgba32(alloc_type& alloc) : base_type(alloc) {} //---------------------------------------------------------------- span_pattern_rgba32(alloc_type& alloc, const rendering_buffer& src, unsigned offset_x, unsigned offset_y) : base_type(alloc, src, offset_x, offset_y, 0) {} //-------------------------------------------------------------------- color_type* generate(int x, int y, unsigned len) { color_type* span = base_type::allocator().span(); unsigned sx = (base_type::offset_x() + x) % base_type::source_image().width(); unsigned wp = base_type::source_image().width() << 2; const int8u* p = base_type::source_image().row((base_type::offset_y() + y) % base_type::source_image().height()); p += sx << 2; do { span->r = p[Order::R]; span->g = p[Order::G]; span->b = p[Order::B]; span->a = p[Order::A]; p += 4; ++sx; ++span; if(sx >= base_type::source_image().width()) { sx -= base_type::source_image().width(); p -= wp; } } while(--len); return base_type::allocator().span(); } }; } #endif aggdraw-1.3.14/agg2/include/agg_span_solid.h000066400000000000000000000041031417726601400206070ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // span_solid_rgba8 // //---------------------------------------------------------------------------- #ifndef AGG_SPAN_SOLID_INCLUDED #define AGG_SPAN_SOLID_INCLUDED #include "agg_basics.h" #include "agg_span_generator.h" namespace agg { //--------------------------------------------------------------span_solid template > class span_solid : public span_generator { public: typedef Allocator alloc_type; typedef ColorT color_type; typedef span_generator base_type; //-------------------------------------------------------------------- span_solid(alloc_type& alloc) : base_type(alloc) {} //-------------------------------------------------------------------- void color(const color_type& c) { m_color = c; } const color_type& color() const { return m_color; } //-------------------------------------------------------------------- color_type* generate(int x, int y, unsigned len) { color_type* span = base_type::allocator().span(); do { *span++ = m_color; } while(--len); return base_type::allocator().span(); } private: color_type m_color; }; } #endif aggdraw-1.3.14/agg2/include/agg_trans_affine.h000066400000000000000000000306301417726601400211170ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Affine transformation classes. // //---------------------------------------------------------------------------- #ifndef AGG_TRANS_AFFINE_INCLUDED #define AGG_TRANS_AFFINE_INCLUDED #include #include "agg_basics.h" namespace agg { const double affine_epsilon = 1e-14; // About of precision of doubles //============================================================trans_affine // // See Implementation agg_trans_affine.cpp // // Affine transformation are linear transformations in Cartesian coordinates // (strictly speaking not only in Cartesian, but for the beginning we will // think so). They are rotation, scaling, translation and skewing. // After any affine transformation a line segment remains a line segment // and it will never become a curve. // // There will be no math about matrix calculations, since it has been // described many times. Ask yourself a very simple question: // "why do we need to understand and use some matrix stuff instead of just // rotating, scaling and so on". The answers are: // // 1. Any combination of transformations can be done by only 4 multiplications // and 4 additions in floating point. // 2. One matrix transformation is equivalent to the number of consecutive // discrete transformations, i.e. the matrix "accumulates" all transformations // in the order of their settings. Suppose we have 4 transformations: // * rotate by 30 degrees, // * scale X to 2.0, // * scale Y to 1.5, // * move to (100, 100). // The result will depend on the order of these transformations, // and the advantage of matrix is that the sequence of discret calls: // rotate(30), scaleX(2.0), scaleY(1.5), move(100,100) // will have exactly the same result as the following matrix transformations: // // affine_matrix m; // m *= rotate_matrix(30); // m *= scaleX_matrix(2.0); // m *= scaleY_matrix(1.5); // m *= move_matrix(100,100); // // m.transform_my_point_at_last(x, y); // // What is the good of it? In real life we will set-up the matrix only once // and then transform many points, let alone the convenience to set any // combination of transformations. // // So, how to use it? Very easy - literally as it's shown above. Not quite, // let us write a correct example: // // agg::trans_affine m; // m *= agg::trans_affine_rotation(30.0 * 3.1415926 / 180.0); // m *= agg::trans_affine_scaling(2.0, 1.5); // m *= agg::trans_affine_translation(100.0, 100.0); // m.transform(&x, &y); // // The affine matrix is all you need to perform any linear transformation, // but all transformations have origin point (0,0). It means that we need to // use 2 translations if we want to rotate someting around (100,100): // // m *= agg::trans_affine_translation(-100.0, -100.0); // move to (0,0) // m *= agg::trans_affine_rotation(30.0 * 3.1415926 / 180.0); // rotate // m *= agg::trans_affine_translation(100.0, 100.0); // move back to (100,100) //---------------------------------------------------------------------- class trans_affine { public: //------------------------------------------ Construction // Construct an identity matrix - it does not transform anything trans_affine() : m0(1.0), m1(0.0), m2(0.0), m3(1.0), m4(0.0), m5(0.0) {} // Construct a custom matrix. Usually used in derived classes trans_affine(double v0, double v1, double v2, double v3, double v4, double v5) : m0(v0), m1(v1), m2(v2), m3(v3), m4(v4), m5(v5) {} // Construct a matrix to transform a parallelogram to another one. trans_affine(const double* rect, const double* parl) { parl_to_parl(rect, parl); } // Construct a matrix to transform a rectangle to a parallelogram. trans_affine(double x1, double y1, double x2, double y2, const double* parl) { rect_to_parl(x1, y1, x2, y2, parl); } // Construct a matrix to transform a parallelogram to a rectangle. trans_affine(const double* parl, double x1, double y1, double x2, double y2) { parl_to_rect(parl, x1, y1, x2, y2); } //---------------------------------- Parellelogram transformations // Calculate a matrix to transform a parallelogram to another one. // src and dst are pointers to arrays of three points // (double[6], x,y,...) that identify three corners of the // parallelograms assuming implicit fourth points. // There are also transformations rectangtle to parallelogram and // parellelogram to rectangle const trans_affine& parl_to_parl(const double* src, const double* dst); const trans_affine& rect_to_parl(double x1, double y1, double x2, double y2, const double* parl); const trans_affine& parl_to_rect(const double* parl, double x1, double y1, double x2, double y2); //------------------------------------------ Operations // Reset - actually load an identity matrix const trans_affine& reset(); // Multiply matrix to another one const trans_affine& multiply(const trans_affine& m); // Multiply "m" to "this" and assign the result to "this" const trans_affine& premultiply(const trans_affine& m); // Invert matrix. Do not try to invert degenerate matrices, // there's no check for validity. If you set scale to 0 and // then try to invert matrix, expect unpredictable result. const trans_affine& invert(); // Mirroring around X const trans_affine& flip_x(); // Mirroring around Y const trans_affine& flip_y(); //------------------------------------------- Load/Store // Store matrix to an array [6] of double void store_to(double* m) const { *m++ = m0; *m++ = m1; *m++ = m2; *m++ = m3; *m++ = m4; *m++ = m5; } // Load matrix from an array [6] of double const trans_affine& load_from(const double* m) { m0 = *m++; m1 = *m++; m2 = *m++; m3 = *m++; m4 = *m++; m5 = *m++; return *this; } //------------------------------------------- Operators // Multiply current matrix to another one const trans_affine& operator *= (const trans_affine& m) { return multiply(m); } // Multiply current matrix to another one and return // the result in a separete matrix. trans_affine operator * (const trans_affine& m) { return trans_affine(*this).multiply(m); } // Calculate and return the inverse matrix trans_affine operator ~ () const { trans_affine ret = *this; return ret.invert(); } // Equal operator with default epsilon bool operator == (const trans_affine& m) const { return is_equal(m, affine_epsilon); } // Not Equal operator with default epsilon bool operator != (const trans_affine& m) const { return !is_equal(m, affine_epsilon); } //-------------------------------------------- Transformations // Direct transformation x and y void transform(double* x, double* y) const; // Inverse transformation x and y. It works slower than the // direct transformation, so if the performance is critical // it's better to invert() the matrix and then use transform() void inverse_transform(double* x, double* y) const; //-------------------------------------------- Auxiliary // Calculate the determinant of matrix double determinant() const { return 1.0 / (m0 * m3 - m1 * m2); } // Get the average scale (by X and Y). // Basically used to calculate the approximation_scale when // decomposinting curves into line segments. double scale() const; // Check to see if it's an identity matrix bool is_identity(double epsilon = affine_epsilon) const; // Check to see if two matrices are equal bool is_equal(const trans_affine& m, double epsilon = affine_epsilon) const; // Determine the major parameters. Use carefully considering degenerate matrices double rotation() const; void translation(double* dx, double* dy) const; void scaling(double* sx, double* sy) const; private: double m0; double m1; double m2; double m3; double m4; double m5; }; //------------------------------------------------------------------------ inline void trans_affine::transform(double* x, double* y) const { register double tx = *x; *x = tx * m0 + *y * m2 + m4; *y = tx * m1 + *y * m3 + m5; } //------------------------------------------------------------------------ inline void trans_affine::inverse_transform(double* x, double* y) const { register double d = determinant(); register double a = (*x - m4) * d; register double b = (*y - m5) * d; *x = a * m3 - b * m2; *y = b * m0 - a * m1; } //------------------------------------------------------------------------ inline double trans_affine::scale() const { double x = 0.707106781 * m0 + 0.707106781 * m2; double y = 0.707106781 * m1 + 0.707106781 * m3; return sqrt(x*x + y*y); } //------------------------------------------------------------------------ inline const trans_affine& trans_affine::premultiply(const trans_affine& m) { trans_affine t = m; return *this = t.multiply(*this); } //====================================================trans_affine_rotation // Rotation matrix. sin() and cos() are calculated twice for the same angle. // There's no harm because the performance of sin()/cos() is very good on all // modern processors. Besides, this operation is not going to be invoked too // often. class trans_affine_rotation : public trans_affine { public: trans_affine_rotation(double a) : trans_affine(cos(a), sin(a), -sin(a), cos(a), 0.0, 0.0) {} }; //====================================================trans_affine_scaling // Scaling matrix. sx, sy - scale coefficients by X and Y respectively class trans_affine_scaling : public trans_affine { public: trans_affine_scaling(double sx, double sy) : trans_affine(sx, 0.0, 0.0, sy, 0.0, 0.0) {} trans_affine_scaling(double s) : trans_affine(s, 0.0, 0.0, s, 0.0, 0.0) {} }; //================================================trans_affine_translation // Translation matrix class trans_affine_translation : public trans_affine { public: trans_affine_translation(double tx, double ty) : trans_affine(1.0, 0.0, 0.0, 1.0, tx, ty) {} }; //====================================================trans_affine_skewing // Sckewing (shear) matrix class trans_affine_skewing : public trans_affine { public: trans_affine_skewing(double sx, double sy) : trans_affine(1.0, tan(sy), tan(sx), 1.0, 0.0, 0.0) {} }; } #endif aggdraw-1.3.14/agg2/include/agg_trans_bilinear.h000066400000000000000000000106661417726601400214630ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Bilinear 2D transformations // //---------------------------------------------------------------------------- #ifndef AGG_TRANS_BILINEAR_INCLUDED #define AGG_TRANS_BILINEAR_INCLUDED #include "agg_basics.h" #include "agg_simul_eq.h" namespace agg { //==========================================================trans_bilinear class trans_bilinear { public: //-------------------------------------------------------------------- trans_bilinear() : m_valid(false) {} //-------------------------------------------------------------------- // Arbitrary quadrangle transformations trans_bilinear(const double* src, const double* dst) { quad_to_quad(src, dst); } //-------------------------------------------------------------------- // Direct transformations trans_bilinear(double x1, double y1, double x2, double y2, const double* quad) { rect_to_quad(x1, y1, x2, y2, quad); } //-------------------------------------------------------------------- // Reverse transformations trans_bilinear(const double* quad, double x1, double y1, double x2, double y2) { quad_to_rect(quad, x1, y1, x2, y2); } //-------------------------------------------------------------------- // Set the transformations using two arbitrary quadrangles. void quad_to_quad(const double* src, const double* dst) { double left[4][4]; double right[4][2]; unsigned i; for(i = 0; i < 4; i++) { unsigned ix = i * 2; unsigned iy = ix + 1; left[i][0] = 1.0; left[i][1] = src[ix] * src[iy]; left[i][2] = src[ix]; left[i][3] = src[iy]; right[i][0] = dst[ix]; right[i][1] = dst[iy]; } m_valid = simul_eq<4, 2>::solve(left, right, m_mtx); } //-------------------------------------------------------------------- // Set the direct transformations, i.e., rectangle -> quadrangle void rect_to_quad(double x1, double y1, double x2, double y2, const double* quad) { double src[8]; src[0] = src[6] = x1; src[2] = src[4] = x2; src[1] = src[3] = y1; src[5] = src[7] = y2; quad_to_quad(src, quad); } //-------------------------------------------------------------------- // Set the reverse transformations, i.e., quadrangle -> rectangle void quad_to_rect(const double* quad, double x1, double y1, double x2, double y2) { double dst[8]; dst[0] = dst[6] = x1; dst[2] = dst[4] = x2; dst[1] = dst[3] = y1; dst[5] = dst[7] = y2; quad_to_quad(quad, dst); } //-------------------------------------------------------------------- // Check if the equations were solved successfully bool is_valid() const { return m_valid; } //-------------------------------------------------------------------- // Transform a point (x, y) void transform(double* x, double* y) const { double tx = *x; double ty = *y; double xy = tx * ty; *x = m_mtx[0][0] + m_mtx[1][0] * xy + m_mtx[2][0] * tx + m_mtx[3][0] * ty; *y = m_mtx[0][1] + m_mtx[1][1] * xy + m_mtx[2][1] * tx + m_mtx[3][1] * ty; } private: double m_mtx[4][2]; bool m_valid; }; } #endif aggdraw-1.3.14/agg2/include/agg_trans_double_path.h000066400000000000000000000101331417726601400221510ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_TRANS_DOUBLE_PATH_INCLUDED #define AGG_TRANS_DOUBLE_PATH_INCLUDED #include "agg_basics.h" #include "agg_vertex_sequence.h" namespace agg { // See also: agg_trans_double_path.cpp // //-------------------------------------------------------trans_double_path class trans_double_path { enum status_e { initial, making_path, ready }; public: typedef vertex_sequence vertex_storage; trans_double_path(); //-------------------------------------------------------------------- void base_length(double v) { m_base_length = v; } double base_length() const { return m_base_length; } //-------------------------------------------------------------------- void base_height(double v) { m_base_height = v; } double base_height() const { return m_base_height; } //-------------------------------------------------------------------- void preserve_x_scale(bool f) { m_preserve_x_scale = f; } bool preserve_x_scale() const { return m_preserve_x_scale; } //-------------------------------------------------------------------- void reset(); void move_to1(double x, double y); void line_to1(double x, double y); void move_to2(double x, double y); void line_to2(double x, double y); void finalize_paths(); //-------------------------------------------------------------------- template void add_paths(VertexSource1& vs1, VertexSource2& vs2, unsigned path1_id=0, unsigned path2_id=0) { double x; double y; unsigned cmd; vs1.rewind(path1_id); while(!is_stop(cmd = vs1.vertex(&x, &y))) { if(is_move_to(cmd)) { move_to1(x, y); } else { if(is_vertex(cmd)) { line_to1(x, y); } } } vs2.rewind(path2_id); while(!is_stop(cmd = vs2.vertex(&x, &y))) { if(is_move_to(cmd)) { move_to2(x, y); } else { if(is_vertex(cmd)) { line_to2(x, y); } } } finalize_paths(); } //-------------------------------------------------------------------- double total_length1() const; double total_length2() const; void transform(double *x, double *y) const; private: double finalize_path(vertex_storage& vertices); void transform1(const vertex_storage& vertices, double kindex, double kx, double *x, double* y) const; vertex_storage m_src_vertices1; vertex_storage m_src_vertices2; double m_base_length; double m_base_height; double m_kindex1; double m_kindex2; status_e m_status1; status_e m_status2; bool m_preserve_x_scale; }; } #endif aggdraw-1.3.14/agg2/include/agg_trans_perspective.h000066400000000000000000000117441417726601400222250ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Perspective 2D transformations // //---------------------------------------------------------------------------- #ifndef AGG_TRANS_PERSPECTIVE_INCLUDED #define AGG_TRANS_PERSPECTIVE_INCLUDED #include "agg_basics.h" #include "agg_simul_eq.h" namespace agg { //=======================================================trans_perspective class trans_perspective { public: //-------------------------------------------------------------------- trans_perspective() : m_valid(false) {} //-------------------------------------------------------------------- // Arbitrary quadrangle transformations trans_perspective(const double* src, const double* dst) { quad_to_quad(src, dst); } //-------------------------------------------------------------------- // Direct transformations trans_perspective(double x1, double y1, double x2, double y2, const double* quad) { rect_to_quad(x1, y1, x2, y2, quad); } //-------------------------------------------------------------------- // Reverse transformations trans_perspective(const double* quad, double x1, double y1, double x2, double y2) { quad_to_rect(quad, x1, y1, x2, y2); } //-------------------------------------------------------------------- // Set the transformations using two arbitrary quadrangles. void quad_to_quad(const double* src, const double* dst) { double left[8][8]; double right[8][1]; unsigned i; for (i = 0; i < 4; i++) { unsigned ix = i * 2; unsigned iy = ix + 1; left[ix][0] = 1.0; left[ix][1] = src[ix]; left[ix][2] = src[iy]; left[ix][3] = 0.0; left[ix][4] = 0.0; left[ix][5] = 0.0; left[ix][6] = -src[ix] * dst[ix]; left[ix][7] = -src[iy] * dst[ix]; right[ix][0] = dst[ix]; left[iy][0] = 0.0; left[iy][1] = 0.0; left[iy][2] = 0.0; left[iy][3] = 1.0; left[iy][4] = src[ix]; left[iy][5] = src[iy]; left[iy][6] = -src[ix] * dst[iy]; left[iy][7] = -src[iy] * dst[iy]; right[iy][0] = dst[iy]; } m_valid = simul_eq<8, 1>::solve(left, right, m_mtx); } //-------------------------------------------------------------------- // Set the direct transformations, i.e., rectangle -> quadrangle void rect_to_quad(double x1, double y1, double x2, double y2, const double* quad) { double src[8]; src[0] = src[6] = x1; src[2] = src[4] = x2; src[1] = src[3] = y1; src[5] = src[7] = y2; quad_to_quad(src, quad); } //-------------------------------------------------------------------- // Set the reverse transformations, i.e., quadrangle -> rectangle void quad_to_rect(const double* quad, double x1, double y1, double x2, double y2) { double dst[8]; dst[0] = dst[6] = x1; dst[2] = dst[4] = x2; dst[1] = dst[3] = y1; dst[5] = dst[7] = y2; quad_to_quad(quad, dst); } //-------------------------------------------------------------------- // Check if the equations were solved successfully bool is_valid() const { return m_valid; } //-------------------------------------------------------------------- // Transform a point (x, y) void transform(double* x, double* y) const { double tx = *x; double ty = *y; double d = 1.0 / (m_mtx[6][0] * tx + m_mtx[7][0] * ty + 1.0); *x = (m_mtx[0][0] + m_mtx[1][0] * tx + m_mtx[2][0] * ty) * d; *y = (m_mtx[3][0] + m_mtx[4][0] * tx + m_mtx[5][0] * ty) * d; } private: double m_mtx[8][1]; bool m_valid; }; } #endif aggdraw-1.3.14/agg2/include/agg_trans_single_path.h000066400000000000000000000056461417726601400221750ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_TRANS_SINGLE_PATH_INCLUDED #define AGG_TRANS_SINGLE_PATH_INCLUDED #include "agg_basics.h" #include "agg_vertex_sequence.h" namespace agg { // See also: agg_trans_single_path.cpp // //-------------------------------------------------------trans_single_path class trans_single_path { enum status_e { initial, making_path, ready }; public: typedef vertex_sequence vertex_storage; trans_single_path(); //-------------------------------------------------------------------- void base_length(double v) { m_base_length = v; } double base_length() const { return m_base_length; } //-------------------------------------------------------------------- void preserve_x_scale(bool f) { m_preserve_x_scale = f; } bool preserve_x_scale() const { return m_preserve_x_scale; } //-------------------------------------------------------------------- void reset(); void move_to(double x, double y); void line_to(double x, double y); void finalize_path(); //-------------------------------------------------------------------- template void add_path(VertexSource& vs, unsigned path_id=0) { double x; double y; unsigned cmd; vs.rewind(path_id); while(!is_stop(cmd = vs.vertex(&x, &y))) { if(is_move_to(cmd)) { move_to(x, y); } else { if(is_vertex(cmd)) { line_to(x, y); } } } finalize_path(); } //-------------------------------------------------------------------- double total_length() const; void transform(double *x, double *y) const; private: vertex_storage m_src_vertices; double m_base_length; double m_kindex; status_e m_status; bool m_preserve_x_scale; }; } #endif aggdraw-1.3.14/agg2/include/agg_trans_viewport.h000066400000000000000000000255701417726601400215550ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Viewport transformer - simple orthogonal conversions from world coordinates // to screen (device) ones. // //---------------------------------------------------------------------------- #ifndef AGG_TRANS_VIEWPORT_INCLUDED #define AGG_TRANS_VIEWPORT_INCLUDED #include #include "agg_basics.h" namespace agg { enum aspect_ratio_e { aspect_ratio_stretch, aspect_ratio_meet, aspect_ratio_slice }; //----------------------------------------------------------trans_viewport class trans_viewport { public: //------------------------------------------------------------------- trans_viewport() : m_world_x1(0.0), m_world_y1(0.0), m_world_x2(1.0), m_world_y2(1.0), m_device_x1(0.0), m_device_y1(0.0), m_device_x2(1.0), m_device_y2(1.0), m_aspect(aspect_ratio_stretch), m_align_x(0.5), m_align_y(0.5), m_wx1(0.0), m_wy1(0.0), m_wx2(1.0), m_wy2(1.0), m_dx1(0.0), m_dy1(0.0), m_kx(1.0), m_ky(1.0) {} //------------------------------------------------------------------- void preserve_aspect_ratio(double alignx, double aligny, aspect_ratio_e aspect) { m_align_x = alignx; m_align_y = aligny; m_aspect = aspect; update(); } //------------------------------------------------------------------- void device_viewport(double x1, double y1, double x2, double y2) { m_device_x1 = x1; m_device_y1 = y1; m_device_x2 = x2; m_device_y2 = y2; update(); } //------------------------------------------------------------------- void world_viewport(double x1, double y1, double x2, double y2) { m_world_x1 = x1; m_world_y1 = y1; m_world_x2 = x2; m_world_y2 = y2; update(); } //------------------------------------------------------------------- void device_viewport(double* x1, double* y1, double* x2, double* y2) const { *x1 = m_device_x1; *y1 = m_device_y1; *x2 = m_device_x2; *y2 = m_device_y2; } //------------------------------------------------------------------- void world_viewport(double* x1, double* y1, double* x2, double* y2) const { *x1 = m_world_x1; *y1 = m_world_y1; *x2 = m_world_x2; *y2 = m_world_y2; } //------------------------------------------------------------------- void world_viewport_actual(double* x1, double* y1, double* x2, double* y2) const { *x1 = m_wx1; *y1 = m_wy1; *x2 = m_wx2; *y2 = m_wy2; } //------------------------------------------------------------------- double align_x() const { return m_align_x; } double align_y() const { return m_align_y; } aspect_ratio_e aspect_ratio() const { return m_aspect; } //------------------------------------------------------------------- void transform(double* x, double* y) const { *x = (*x - m_wx1) * m_kx + m_dx1; *y = (*y - m_wy1) * m_ky + m_dy1; } //------------------------------------------------------------------- void inverse_transform(double* x, double* y) const { *x = (*x - m_dx1) / m_kx + m_wx1; *y = (*y - m_dy1) / m_ky + m_wy1; } //------------------------------------------------------------------- double scale() const { return (m_kx + m_ky) * 0.5; } //------------------------------------------------------------------- unsigned byte_size() const { return sizeof(m_world_x1) + sizeof(m_world_y1) + sizeof(m_world_x2) + sizeof(m_world_y2) + sizeof(m_device_x1) + sizeof(m_device_y1) + sizeof(m_device_x2) + sizeof(m_device_y2) + sizeof(m_aspect) + sizeof(m_align_x) + sizeof(m_align_y) + sizeof(m_wx1) + sizeof(m_wy1) + sizeof(m_wx2) + sizeof(m_wy2) + sizeof(m_dx1) + sizeof(m_dy1) + sizeof(m_kx) + sizeof(m_ky); } void serialize(int8u* ptr) const { memcpy(ptr, &m_world_x1, sizeof(m_world_x1)); ptr += sizeof(m_world_x1); memcpy(ptr, &m_world_y1, sizeof(m_world_y1)); ptr += sizeof(m_world_y1); memcpy(ptr, &m_world_x2, sizeof(m_world_x2)); ptr += sizeof(m_world_x2); memcpy(ptr, &m_world_y2, sizeof(m_world_y2)); ptr += sizeof(m_world_y2); memcpy(ptr, &m_device_x1, sizeof(m_device_x1)); ptr += sizeof(m_device_x1); memcpy(ptr, &m_device_y1, sizeof(m_device_y1)); ptr += sizeof(m_device_y1); memcpy(ptr, &m_device_x2, sizeof(m_device_x2)); ptr += sizeof(m_device_x2); memcpy(ptr, &m_device_y2, sizeof(m_device_y2)); ptr += sizeof(m_device_y2); memcpy(ptr, &m_aspect, sizeof(m_aspect)); ptr += sizeof(m_aspect); memcpy(ptr, &m_align_x, sizeof(m_align_x)); ptr += sizeof(m_align_x); memcpy(ptr, &m_align_y, sizeof(m_align_y)); ptr += sizeof(m_align_y); memcpy(ptr, &m_wx1, sizeof(m_wx1)); ptr += sizeof(m_wx1); memcpy(ptr, &m_wy1, sizeof(m_wy1)); ptr += sizeof(m_wy1); memcpy(ptr, &m_wx2, sizeof(m_wx2)); ptr += sizeof(m_wx2); memcpy(ptr, &m_wy2, sizeof(m_wy2)); ptr += sizeof(m_wy2); memcpy(ptr, &m_dx1, sizeof(m_dx1)); ptr += sizeof(m_dx1); memcpy(ptr, &m_dy1, sizeof(m_dy1)); ptr += sizeof(m_dy1); memcpy(ptr, &m_kx, sizeof(m_kx)); ptr += sizeof(m_kx); memcpy(ptr, &m_ky, sizeof(m_ky)); ptr += sizeof(m_ky); } void deserialize(const int8u* ptr) { memcpy(&m_world_x1, ptr, sizeof(m_world_x1)); ptr += sizeof(m_world_x1); memcpy(&m_world_y1, ptr, sizeof(m_world_y1)); ptr += sizeof(m_world_y1); memcpy(&m_world_x2, ptr, sizeof(m_world_x2)); ptr += sizeof(m_world_x2); memcpy(&m_world_y2, ptr, sizeof(m_world_y2)); ptr += sizeof(m_world_y2); memcpy(&m_device_x1, ptr, sizeof(m_device_x1)); ptr += sizeof(m_device_x1); memcpy(&m_device_y1, ptr, sizeof(m_device_y1)); ptr += sizeof(m_device_y1); memcpy(&m_device_x2, ptr, sizeof(m_device_x2)); ptr += sizeof(m_device_x2); memcpy(&m_device_y2, ptr, sizeof(m_device_y2)); ptr += sizeof(m_device_y2); memcpy(&m_aspect, ptr, sizeof(m_aspect)); ptr += sizeof(m_aspect); memcpy(&m_align_x, ptr, sizeof(m_align_x)); ptr += sizeof(m_align_x); memcpy(&m_align_y, ptr, sizeof(m_align_y)); ptr += sizeof(m_align_y); memcpy(&m_wx1, ptr, sizeof(m_wx1)); ptr += sizeof(m_wx1); memcpy(&m_wy1, ptr, sizeof(m_wy1)); ptr += sizeof(m_wy1); memcpy(&m_wx2, ptr, sizeof(m_wx2)); ptr += sizeof(m_wx2); memcpy(&m_wy2, ptr, sizeof(m_wy2)); ptr += sizeof(m_wy2); memcpy(&m_dx1, ptr, sizeof(m_dx1)); ptr += sizeof(m_dx1); memcpy(&m_dy1, ptr, sizeof(m_dy1)); ptr += sizeof(m_dy1); memcpy(&m_kx, ptr, sizeof(m_kx)); ptr += sizeof(m_kx); memcpy(&m_ky, ptr, sizeof(m_ky)); ptr += sizeof(m_ky); } private: void update(); double m_world_x1; double m_world_y1; double m_world_x2; double m_world_y2; double m_device_x1; double m_device_y1; double m_device_x2; double m_device_y2; aspect_ratio_e m_aspect; double m_align_x; double m_align_y; double m_wx1; double m_wy1; double m_wx2; double m_wy2; double m_dx1; double m_dy1; double m_kx; double m_ky; }; //----------------------------------------------------------------------- inline void trans_viewport::update() { double world_x1 = m_world_x1; double world_y1 = m_world_y1; double world_x2 = m_world_x2; double world_y2 = m_world_y2; double device_x1 = m_device_x1; double device_y1 = m_device_y1; double device_x2 = m_device_x2; double device_y2 = m_device_y2; if(m_aspect != aspect_ratio_stretch) { double d; m_kx = (device_x2 - device_x1) / (world_x2 - world_x1); m_ky = (device_y2 - device_y1) / (world_y2 - world_y1); if((m_aspect == aspect_ratio_meet) == (m_kx < m_ky)) { d = (world_y2 - world_y1) * m_ky / m_kx; world_y1 += (world_y2 - world_y1 - d) * m_align_y; world_y2 = world_y1 + d; } else { d = (world_x2 - world_x1) * m_kx / m_ky; world_x1 += (world_x2 - world_x1 - d) * m_align_x; world_x2 = world_x1 + d; } } m_wx1 = world_x1; m_wy1 = world_y1; m_wx2 = world_x2; m_wy2 = world_y2; m_dx1 = device_x1; m_dy1 = device_y1; m_kx = (device_x2 - device_x1) / (world_x2 - world_x1); m_ky = (device_y2 - device_y1) / (world_y2 - world_y1); } } #endif aggdraw-1.3.14/agg2/include/agg_trans_warp_magnifier.h000066400000000000000000000027761417726601400226730ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_WARP_MAGNIFIER_INCLUDED #define AGG_WARP_MAGNIFIER_INCLUDED namespace agg { //----------------------------------------------------trans_warp_magnifier // // See Inmplementation agg_trans_warp_magnifier.cpp // class trans_warp_magnifier { public: trans_warp_magnifier() : m_xc(0.0), m_yc(0.0), m_magn(1.0), m_radius(1.0) {} void center(double x, double y) { m_xc = x; m_yc = y; } void magnification(double m) { m_magn = m; } void radius(double r) { m_radius = r; } void transform(double* x, double* y) const; void inverse_transform(double* x, double* y) const; private: double m_xc; double m_yc; double m_magn; double m_radius; }; } #endif aggdraw-1.3.14/agg2/include/agg_vcgen_bspline.h000066400000000000000000000040761417726601400213030ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_VCGEN_BSPLINE_INCLUDED #define AGG_VCGEN_BSPLINE_INCLUDED #include "agg_basics.h" #include "agg_array.h" #include "agg_bspline.h" namespace agg { //==========================================================vcgen_bspline class vcgen_bspline { enum status_e { initial, ready, polygon, end_poly, stop }; public: typedef pod_deque vertex_storage; vcgen_bspline(); void interpolation_step(double v) { m_interpolation_step = v; } double interpolation_step() const { return m_interpolation_step; } // Vertex Generator Interface void remove_all(); void add_vertex(double x, double y, unsigned cmd); // Vertex Source Interface void rewind(unsigned id); unsigned vertex(double* x, double* y); private: vcgen_bspline(const vcgen_bspline&); const vcgen_bspline& operator = (const vcgen_bspline&); vertex_storage m_src_vertices; bspline m_spline_x; bspline m_spline_y; double m_interpolation_step; unsigned m_closed; status_e m_status; unsigned m_src_vertex; double m_cur_abscissa; double m_max_abscissa; }; } #endif aggdraw-1.3.14/agg2/include/agg_vcgen_contour.h000066400000000000000000000052311417726601400213320ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_VCGEN_CONTOUR_INCLUDED #define AGG_VCGEN_CONTOUR_INCLUDED #include "agg_basics.h" #include "agg_vertex_sequence.h" namespace agg { //----------------------------------------------------------vcgen_contour // // See Implementation agg_vcgen_contour.cpp // class vcgen_contour { enum status_e { initial, ready, outline, add_point, end_poly }; public: typedef vertex_sequence vertex_storage; vcgen_contour(); void width(double w) { m_width = w * 0.5; } void miter_limit(double ml) { m_miter_limit = ml; } void miter_limit_theta(double t); void auto_detect_orientation(bool v) { m_auto_detect = v; } double width() const { return m_width * 2.0; } double miter_limit() const { return m_miter_limit; } bool auto_detect_orientation() const { return m_auto_detect; } // Generator interface void remove_all(); void add_vertex(double x, double y, unsigned cmd); // Vertex Source Interface void rewind(unsigned id); unsigned vertex(double* x, double* y); private: vcgen_contour(const vcgen_contour&); const vcgen_contour& operator = (const vcgen_contour&); bool calc_miter(const vertex_dist& v0, const vertex_dist& v1, const vertex_dist& v2); vertex_storage m_src_vertices; double m_width; double m_abs_width; double m_signed_width; double m_miter_limit; status_e m_status; unsigned m_src_vertex; unsigned m_closed; unsigned m_orientation; bool m_auto_detect; double m_x1; double m_y1; double m_x2; double m_y2; }; } #endif aggdraw-1.3.14/agg2/include/agg_vcgen_dash.h000066400000000000000000000055011417726601400205600ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Line dash generator // //---------------------------------------------------------------------------- #ifndef AGG_VCGEN_DASH_INCLUDED #define AGG_VCGEN_DASH_INCLUDED #include "agg_basics.h" #include "agg_vertex_sequence.h" #include "agg_vertex_iterator.h" namespace agg { //---------------------------------------------------------------vcgen_dash // // See Implementation agg_vcgen_dash.cpp // class vcgen_dash { enum { max_dashes = 32 }; enum status_e { initial, ready, polyline, stop }; public: typedef vertex_sequence vertex_storage; vcgen_dash(); void remove_all_dashes(); void add_dash(double dash_len, double gap_len); void dash_start(double ds); void shorten(double s) { m_shorten = s; } double shorten() const { return m_shorten; } // Vertex Generator Interface void remove_all(); void add_vertex(double x, double y, unsigned cmd); // Vertex Source Interface void rewind(unsigned id); unsigned vertex(double* x, double* y); typedef vcgen_dash source_type; typedef vertex_iterator iterator; iterator begin(unsigned id) { return iterator(*this, id); } iterator end() { return iterator(path_cmd_stop); } private: vcgen_dash(const vcgen_dash&); const vcgen_dash& operator = (const vcgen_dash&); void calc_dash_start(double ds); double m_dashes[max_dashes]; double m_total_dash_len; unsigned m_num_dashes; double m_dash_start; double m_shorten; double m_curr_dash_start; unsigned m_curr_dash; double m_curr_rest; const vertex_dist* m_v1; const vertex_dist* m_v2; vertex_storage m_src_vertices; unsigned m_closed; status_e m_status; unsigned m_src_vertex; }; } #endif aggdraw-1.3.14/agg2/include/agg_vcgen_markers_term.h000066400000000000000000000043311417726601400223340ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_VCGEN_MARKERS_TERM_INCLUDED #define AGG_VCGEN_MARKERS_TERM_INCLUDED #include "agg_basics.h" #include "agg_vertex_sequence.h" #include "agg_vertex_iterator.h" namespace agg { //======================================================vcgen_markers_term // // See Implemantation agg_vcgen_markers_term.cpp // Terminal markers generator (arrowhead/arrowtail) // //------------------------------------------------------------------------ class vcgen_markers_term { public: vcgen_markers_term() : m_curr_id(0), m_curr_idx(0) {} // Vertex Generator Interface void remove_all(); void add_vertex(double x, double y, unsigned cmd); // Vertex Source Interface void rewind(unsigned id); unsigned vertex(double* x, double* y); typedef vcgen_markers_term source_type; typedef vertex_iterator iterator; iterator begin(unsigned id) { return iterator(*this, id); } iterator end() { return iterator(path_cmd_stop); } private: vcgen_markers_term(const vcgen_markers_term&); const vcgen_markers_term& operator = (const vcgen_markers_term&); struct coord_type { double x, y; coord_type() {} coord_type(double x_, double y_) : x(x_), y(y_) {} }; typedef pod_deque coord_storage; coord_storage m_markers; unsigned m_curr_id; unsigned m_curr_idx; }; } #endif aggdraw-1.3.14/agg2/include/agg_vcgen_smooth_poly1.h000066400000000000000000000050001417726601400222700ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_VCGEN_SMOOTH_POLY1_INCLUDED #define AGG_VCGEN_SMOOTH_POLY1_INCLUDED #include "agg_basics.h" #include "agg_vertex_sequence.h" namespace agg { //======================================================vcgen_smooth_poly1 // // See Implementation agg_vcgen_smooth_poly1.cpp // Smooth polygon generator // //------------------------------------------------------------------------ class vcgen_smooth_poly1 { enum status_e { initial, ready, polygon, ctrl_b, ctrl_e, ctrl1, ctrl2, end_poly, stop }; public: typedef vertex_sequence vertex_storage; vcgen_smooth_poly1(); void smooth_value(double v) { m_smooth_value = v * 0.5; } double smooth_value() const { return m_smooth_value * 2.0; } // Vertex Generator Interface void remove_all(); void add_vertex(double x, double y, unsigned cmd); // Vertex Source Interface void rewind(unsigned id); unsigned vertex(double* x, double* y); private: vcgen_smooth_poly1(const vcgen_smooth_poly1&); const vcgen_smooth_poly1& operator = (const vcgen_smooth_poly1&); void calculate(const vertex_dist& v0, const vertex_dist& v1, const vertex_dist& v2, const vertex_dist& v3); vertex_storage m_src_vertices; double m_smooth_value; unsigned m_closed; status_e m_status; unsigned m_src_vertex; double m_ctrl1_x; double m_ctrl1_y; double m_ctrl2_x; double m_ctrl2_y; }; } #endif aggdraw-1.3.14/agg2/include/agg_vcgen_stroke.h000066400000000000000000000112121417726601400211440ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_VCGEN_STROKE_INCLUDED #define AGG_VCGEN_STROKE_INCLUDED #include "agg_basics.h" #include "agg_vertex_sequence.h" #include "agg_vertex_iterator.h" namespace agg { // Minimal angle to calculate round joins const double vcgen_stroke_theta = 1e-10; //----vcgen_stroke_theta //============================================================vcgen_stroke // // See Implementation agg_vcgen_stroke.cpp // Stroke generator // //------------------------------------------------------------------------ class vcgen_stroke { enum status_e { initial, ready, cap1, cap2, outline1, close_first, outline2, out_vertices, end_poly1, end_poly2, stop }; public: enum line_cap_e { butt_cap, square_cap, round_cap }; enum line_join_e { miter_join, miter_join_revert, round_join, bevel_join }; struct coord_type { double x, y; coord_type() {} coord_type(double x_, double y_) : x(x_), y(y_) {} }; typedef vertex_sequence vertex_storage; typedef pod_deque coord_storage; vcgen_stroke(); void line_cap(line_cap_e lc) { m_line_cap = lc; } void line_join(line_join_e lj) { m_line_join = lj; } line_cap_e line_cap() const { return m_line_cap; } line_join_e line_join() const { return m_line_join; } void width(double w) { m_width = w * 0.5; } void miter_limit(double ml) { m_miter_limit = ml; } void miter_limit_theta(double t); void approximation_scale(double as) { m_approx_scale = as; } double width() const { return m_width * 2.0; } double miter_limit() const { return m_miter_limit; } double approximation_scale() const { return m_approx_scale; } void shorten(double s) { m_shorten = s; } double shorten() const { return m_shorten; } // Vertex Generator Interface void remove_all(); void add_vertex(double x, double y, unsigned cmd); // Vertex Source Interface void rewind(unsigned id); unsigned vertex(double* x, double* y); typedef vcgen_stroke source_type; typedef vertex_iterator iterator; iterator begin(unsigned id) { return iterator(*this, id); } iterator end() { return iterator(path_cmd_stop); } private: vcgen_stroke(const vcgen_stroke&); const vcgen_stroke& operator = (const vcgen_stroke&); void calc_join(const vertex_dist& v0, const vertex_dist& v1, const vertex_dist& v2, double len1, double len2); void calc_miter(const vertex_dist& v0, const vertex_dist& v1, const vertex_dist& v2, double dx1, double dy1, double dx2, double dy2, bool revert_flag); void calc_arc(double x, double y, double dx1, double dy1, double dx2, double dy2); void calc_cap(const vertex_dist& v0, const vertex_dist& v1, double len); vertex_storage m_src_vertices; coord_storage m_out_vertices; double m_width; double m_miter_limit; double m_approx_scale; double m_shorten; line_cap_e m_line_cap; line_join_e m_line_join; unsigned m_closed; status_e m_status; status_e m_prev_status; unsigned m_src_vertex; unsigned m_out_vertex; }; } #endif aggdraw-1.3.14/agg2/include/agg_vcgen_vertex_sequence.h000066400000000000000000000073631417726601400230560ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_VCGEN_VERTEX_SEQUENCE_INCLUDED #define AGG_VCGEN_VERTEX_SEQUENCE_INCLUDED #include "agg_basics.h" #include "agg_vertex_sequence.h" #include "agg_shorten_path.h" namespace agg { //===================================================vcgen_vertex_sequence class vcgen_vertex_sequence { public: typedef vertex_dist_cmd vertex_type; typedef vertex_sequence vertex_storage; vcgen_vertex_sequence() : m_flags(0), m_cur_vertex(0), m_shorten(0.0), m_ready(false) { } // Vertex Generator Interface void remove_all(); void add_vertex(double x, double y, unsigned cmd); // Vertex Source Interface void rewind(unsigned id); unsigned vertex(double* x, double* y); void shorten(double s) { m_shorten = s; } double shorten() const { return m_shorten; } private: vcgen_vertex_sequence(const vcgen_vertex_sequence&); const vcgen_vertex_sequence& operator = (const vcgen_vertex_sequence&); vertex_storage m_src_vertices; unsigned m_flags; unsigned m_cur_vertex; double m_shorten; bool m_ready; }; //------------------------------------------------------------------------ inline void vcgen_vertex_sequence::remove_all() { m_ready = false; m_src_vertices.remove_all(); m_cur_vertex = 0; m_flags = 0; } //------------------------------------------------------------------------ inline void vcgen_vertex_sequence::add_vertex(double x, double y, unsigned cmd) { m_ready = false; if(is_move_to(cmd)) { m_src_vertices.modify_last(vertex_dist_cmd(x, y, cmd)); } else { if(is_vertex(cmd)) { m_src_vertices.add(vertex_dist_cmd(x, y, cmd)); } else { m_flags = cmd & path_flags_mask; } } } //------------------------------------------------------------------------ inline void vcgen_vertex_sequence::rewind(unsigned) { if(!m_ready) { m_src_vertices.close(is_closed(m_flags)); shorten_path(m_src_vertices, m_shorten, get_close_flag(m_flags)); } m_ready = true; m_cur_vertex = 0; } //------------------------------------------------------------------------ inline unsigned vcgen_vertex_sequence::vertex(double* x, double* y) { if(!m_ready) { rewind(0); } if(m_cur_vertex == m_src_vertices.size()) { ++m_cur_vertex; return path_cmd_end_poly | m_flags; } if(m_cur_vertex > m_src_vertices.size()) { return path_cmd_stop; } vertex_type& v = m_src_vertices[m_cur_vertex++]; *x = v.x; *y = v.y; return v.cmd; } } #endif aggdraw-1.3.14/agg2/include/agg_vertex_iterator.h000066400000000000000000000075641417726601400217200ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // classes: vertex_iterator // vertex_source_adaptor // vertex_source_adaptor_with_id // //---------------------------------------------------------------------------- #ifndef AGG_VERTEX_ITERATOR_INCLUDED #define AGG_VERTEX_ITERATOR_INCLUDED #include "agg_basics.h" namespace agg { //---------------------------------------------------------vertex_iterator template class vertex_iterator { public: vertex_iterator() {} vertex_iterator(unsigned cmd) { m_vertex.cmd = cmd; } vertex_iterator(const vertex_iterator& i) : m_vs(i.m_vs), m_vertex(i.m_vertex) {} vertex_iterator(VertexSource& vs, unsigned id) : m_vs(&vs) { m_vs->rewind(id); m_vertex.cmd = m_vs->vertex(&m_vertex.x, &m_vertex.y); } vertex_iterator& operator++() { m_vertex.cmd = m_vs->vertex(&m_vertex.x, &m_vertex.y); return *this; } const vertex_type& operator*() const { return m_vertex; } const vertex_type* operator->() const { return &m_vertex; } bool operator != (const vertex_iterator& i) { return m_vertex.cmd != i.m_vertex.cmd; } private: VertexSource* m_vs; vertex_type m_vertex; }; //---------------------------------------------------vertex_source_adaptor template class vertex_source_adaptor { public: vertex_source_adaptor(const VertexContainer& container) : m_container(&container) {} void rewind(unsigned) { m_iterator = m_container->begin(); m_end = m_container->end(); } unsigned vertex(double* x, double* y) { unsigned cmd = path_cmd_stop; if(m_iterator != m_end) { *x = m_iterator->x; *y = m_iterator->y; cmd = m_iterator->cmd; ++m_iterator; } return cmd; } private: const VertexContainer* m_container; typename VertexContainer::const_iterator m_iterator; typename VertexContainer::const_iterator m_end; }; //-------------------------------------------vertex_source_adaptor_with_id template class vertex_source_adaptor_with_id { public: vertex_source_adaptor_with_id(const VertexContainer& container) : m_container(&container) {} void rewind(unsigned id) { m_iterator = m_container->begin(id); m_end = m_container->end(); } unsigned vertex(double* x, double* y) { unsigned cmd = path_cmd_stop; if(m_iterator != m_end) { *x = m_iterator->x; *y = m_iterator->y; cmd = m_iterator->cmd; ++m_iterator; } return cmd; } private: const VertexContainer* m_container; typename VertexContainer::const_iterator m_iterator; typename VertexContainer::const_iterator m_end; }; } #endif aggdraw-1.3.14/agg2/include/agg_vertex_sequence.h000066400000000000000000000122241417726601400216640ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // vertex_sequence container and vertex_dist struct // //---------------------------------------------------------------------------- #ifndef AGG_VERTEX_SEQUENCE_INCLUDED #define AGG_VERTEX_SEQUENCE_INCLUDED #include "agg_basics.h" #include "agg_array.h" #include "agg_math.h" namespace agg { //----------------------------------------------------------vertex_sequence // Modified agg::pod_deque. The data is interpreted as a sequence of vertices. // It means that the type T must expose: // // bool operator() (const T& val) // // that is called every time new vertex is being added. The main purpose // of this operator is the possibility to calculate some values during // adding and to return true if the vertex fits some criteria or false if // it doesn't. In the last case the new vertex is not added. // // The simple example is filtering coinciding vertices with calculation // of the distance between the current and previous ones: // // struct vertex_dist // { // double x; // double y; // double dist; // // vertex_dist() {} // vertex_dist(double x_, double y_) : // x(x_), // y(y_), // dist(0.0) // { // } // // bool operator () (const vertex_dist& val) // { // return (dist = calc_distance(x, y, val.x, val.y)) > EPSILON; // } // }; // // Function close() calls this operator and removes the last vertex if // necessary. //------------------------------------------------------------------------ template class vertex_sequence : public pod_deque { public: typedef pod_deque base_type; void add(const T& val); void modify_last(const T& val); void close(bool remove_flag); }; //------------------------------------------------------------------------ template void vertex_sequence::add(const T& val) { if(base_type::size() > 1) { if(!(*this)[base_type::size() - 2]((*this)[base_type::size() - 1])) { base_type::remove_last(); } } base_type::add(val); } //------------------------------------------------------------------------ template void vertex_sequence::modify_last(const T& val) { base_type::remove_last(); add(val); } //------------------------------------------------------------------------ template void vertex_sequence::close(bool closed) { while(base_type::size() > 1) { if((*this)[base_type::size() - 2]((*this)[base_type::size() - 1])) break; T t = (*this)[base_type::size() - 1]; base_type::remove_last(); modify_last(t); } if(closed) { while(base_type::size() > 1) { if((*this)[base_type::size() - 1]((*this)[0])) break; base_type::remove_last(); } } } // Coinciding points maximal distance (Epsilon) const double vertex_dist_epsilon = 1e-14; //-------------------------------------------------------------vertex_dist // Vertex (x, y) with the distance to the next one. The last vertex has // distance between the last and the first points if the polygon is closed // and 0.0 if it's a polyline. struct vertex_dist { double x; double y; double dist; vertex_dist() {} vertex_dist(double x_, double y_) : x(x_), y(y_), dist(0.0) { } bool operator () (const vertex_dist& val) { bool ret = (dist = calc_distance(x, y, val.x, val.y)) > vertex_dist_epsilon; if(!ret) dist = 1.0 / vertex_dist_epsilon; return ret; } }; //--------------------------------------------------------vertex_dist_cmd // Save as the above but with additional "command" value struct vertex_dist_cmd : public vertex_dist { unsigned cmd; vertex_dist_cmd() {} vertex_dist_cmd(double x_, double y_, unsigned cmd_) : vertex_dist(x_, y_), cmd(cmd_) { } }; } #endif aggdraw-1.3.14/agg2/include/agg_vpgen_clip_polygon.h000066400000000000000000000044031417726601400223540ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_VPGEN_CLIP_POLYGON_INCLUDED #define AGG_VPGEN_CLIP_POLYGON_INCLUDED #include "agg_basics.h" namespace agg { //======================================================vpgen_clip_polygon // // See Implementation agg_vpgen_clip_polygon.cpp // class vpgen_clip_polygon { public: vpgen_clip_polygon() : m_clip_box(0, 0, 1, 1), m_x1(0), m_y1(0), m_clip_flags(0), m_num_vertices(0), m_vertex(0), m_cmd(path_cmd_move_to) { } void clip_box(double x1, double y1, double x2, double y2) { m_clip_box.x1 = x1; m_clip_box.y1 = y1; m_clip_box.x2 = x2; m_clip_box.y2 = y2; m_clip_box.normalize(); } double x1() const { return m_clip_box.x1; } double y1() const { return m_clip_box.y1; } double x2() const { return m_clip_box.x2; } double y2() const { return m_clip_box.y2; } void reset(); void move_to(double x, double y); void line_to(double x, double y); unsigned vertex(double* x, double* y); private: unsigned clipping_flags(double x, double y); private: rect_d m_clip_box; double m_x1; double m_y1; unsigned m_clip_flags; double m_x[4]; double m_y[4]; unsigned m_num_vertices; unsigned m_vertex; unsigned m_cmd; }; } #endif aggdraw-1.3.14/agg2/include/agg_vpgen_segmentator.h000066400000000000000000000032401417726601400222040ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #ifndef AGG_VPGEN_SEGMENTATOR_INCLUDED #define AGG_VPGEN_SEGMENTATOR_INCLUDED #include #include "agg_basics.h" namespace agg { //=======================================================vpgen_segmentator // // See Implementation agg_vpgen_segmentator.cpp // class vpgen_segmentator { public: vpgen_segmentator() : m_approximation_scale(1.0) {} void approximation_scale(double s) { m_approximation_scale = s; } double approximation_scale() const { return m_approximation_scale; } void reset() { m_cmd = path_cmd_stop; } void move_to(double x, double y); void line_to(double x, double y); unsigned vertex(double* x, double* y); private: double m_approximation_scale; double m_x1; double m_y1; double m_dx; double m_dy; double m_dl; double m_ddl; unsigned m_cmd; }; } #endif aggdraw-1.3.14/agg2/include/ctrl/000077500000000000000000000000001417726601400164335ustar00rootroot00000000000000aggdraw-1.3.14/agg2/include/ctrl/agg_cbox_ctrl.h000066400000000000000000000070401417726601400214020ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // classes cbox_ctrl_impl, cbox_ctrl // //---------------------------------------------------------------------------- #ifndef AGG_CBOX_CTRL_INCLUDED #define AGG_CBOX_CTRL_INCLUDED #include "agg_basics.h" #include "agg_conv_stroke.h" #include "agg_gsv_text.h" #include "agg_trans_affine.h" #include "agg_color_rgba.h" #include "agg_ctrl.h" namespace agg { //----------------------------------------------------------cbox_ctrl_impl class cbox_ctrl_impl : public ctrl { public: cbox_ctrl_impl(double x, double y, const char* label, bool flip_y=false); void text_thickness(double t) { m_text_thickness = t; } void text_size(double h, double w=0.0); const char* label() { return m_label; } void label(const char* l); bool status() const { return m_status; } void status(bool st) { m_status = st; } virtual bool in_rect(double x, double y) const; virtual bool on_mouse_button_down(double x, double y); virtual bool on_mouse_button_up(double x, double y); virtual bool on_mouse_move(double x, double y, bool button_flag); virtual bool on_arrow_keys(bool left, bool right, bool down, bool up); // Vertex soutce interface unsigned num_paths() { return 3; }; void rewind(unsigned id); unsigned vertex(double* x, double* y); private: double m_text_thickness; double m_text_height; double m_text_width; char m_label[128]; bool m_status; double m_vx[32]; double m_vy[32]; gsv_text m_text; conv_stroke m_text_poly; unsigned m_idx; unsigned m_vertex; }; //----------------------------------------------------------cbox_ctrl_impl template class cbox_ctrl : public cbox_ctrl_impl { public: cbox_ctrl(double x, double y, const char* label, bool flip_y=false) : cbox_ctrl_impl(x, y, label, flip_y), m_text_color(rgba(0.0, 0.0, 0.0)), m_inactive_color(rgba(0.0, 0.0, 0.0)), m_active_color(rgba(0.4, 0.0, 0.0)) { m_colors[0] = &m_inactive_color; m_colors[1] = &m_text_color; m_colors[2] = &m_active_color; } void text_color(const ColorT& c) { m_text_color = c; } void inactive_color(const ColorT& c) { m_inactive_color = c; } void active_color(const ColorT& c) { m_active_color = c; } const ColorT& color(unsigned i) const { return *m_colors[i]; } private: cbox_ctrl(const cbox_ctrl&); const cbox_ctrl& operator = (const cbox_ctrl&); ColorT m_text_color; ColorT m_inactive_color; ColorT m_active_color; ColorT* m_colors[3]; }; } #endif aggdraw-1.3.14/agg2/include/ctrl/agg_ctrl.h000066400000000000000000000062331417726601400203720ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Function render_ctrl // //---------------------------------------------------------------------------- #ifndef AGG_CTRL_INCLUDED #define AGG_CTRL_INCLUDED #include "agg_trans_affine.h" #include "agg_renderer_scanline.h" namespace agg { //--------------------------------------------------------------------ctrl class ctrl { public: //-------------------------------------------------------------------- ctrl(double x1, double y1, double x2, double y2, bool flip_y) : m_x1(x1), m_y1(y1), m_x2(x2), m_y2(y2), m_flip_y(flip_y), m_mtx(0) { } //-------------------------------------------------------------------- virtual bool in_rect(double x, double y) const = 0; virtual bool on_mouse_button_down(double x, double y) = 0; virtual bool on_mouse_button_up(double x, double y) = 0; virtual bool on_mouse_move(double x, double y, bool button_flag) = 0; virtual bool on_arrow_keys(bool left, bool right, bool down, bool up) = 0; //-------------------------------------------------------------------- void transform(const trans_affine& mtx) { m_mtx = &mtx; } void no_transform() { m_mtx = 0; } //-------------------------------------------------------------------- void transform_xy(double* x, double* y) const { if(m_flip_y) *y = m_y1 + m_y2 - *y; if(m_mtx) m_mtx->transform(x, y); } //-------------------------------------------------------------------- void inverse_transform_xy(double* x, double* y) const { if(m_mtx) m_mtx->inverse_transform(x, y); if(m_flip_y) *y = m_y1 + m_y2 - *y; } private: ctrl(const ctrl&); const ctrl& operator = (const ctrl&); protected: double m_x1; double m_y1; double m_x2; double m_y2; private: bool m_flip_y; const trans_affine* m_mtx; }; //-------------------------------------------------------------------- template void render_ctrl(Rasterizer& ras, Scanline& sl, Renderer& r, Ctrl& c) { unsigned i; for(i = 0; i < c.num_paths(); i++) { ras.reset(); ras.add_path(c, i); r.color(c.color(i)); render_scanlines(ras, sl, r); } } } #endif aggdraw-1.3.14/agg2/include/ctrl/agg_gamma_ctrl.h000066400000000000000000000141121417726601400215270ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // class gamma_ctrl // //---------------------------------------------------------------------------- #ifndef AGG_GAMMA_CTRL_INCLUDED #define AGG_GAMMA_CTRL_INCLUDED #include "agg_basics.h" #include "agg_gamma_spline.h" #include "agg_ellipse.h" #include "agg_conv_stroke.h" #include "agg_gsv_text.h" #include "agg_trans_affine.h" #include "agg_color_rgba.h" #include "agg_ctrl.h" namespace agg { //------------------------------------------------------------------------ // Class that can be used to create an interactive control to set up // gamma arrays. //------------------------------------------------------------------------ class gamma_ctrl_impl : public ctrl { public: gamma_ctrl_impl(double x1, double y1, double x2, double y2, bool flip_y=false); // Set other parameters void border_width(double t, double extra=0.0); void curve_width(double t) { m_curve_width = t; } void grid_width(double t) { m_grid_width = t; } void text_thickness(double t) { m_text_thickness = t; } void text_size(double h, double w=0.0); void point_size(double s) { m_point_size = s; } // Event handlers. Just call them if the respective events // in your system occure. The functions return true if redrawing // is required. virtual bool in_rect(double x, double y) const; virtual bool on_mouse_button_down(double x, double y); virtual bool on_mouse_button_up(double x, double y); virtual bool on_mouse_move(double x, double y, bool button_flag); virtual bool on_arrow_keys(bool left, bool right, bool down, bool up); void change_active_point(); // A copy of agg::gamma_spline interface void values(double kx1, double ky1, double kx2, double ky2); void values(double* kx1, double* ky1, double* kx2, double* ky2) const; const unsigned char* gamma() const { return m_gamma_spline.gamma(); } double y(double x) const { return m_gamma_spline.y(x); } double operator() (double x) const { return m_gamma_spline.y(x); } const gamma_spline& get_gamma_spline() const { return m_gamma_spline; } // Vertex soutce interface unsigned num_paths() { return 7; } void rewind(unsigned idx); unsigned vertex(double* x, double* y); private: void calc_spline_box(); void calc_points(); void calc_values(); gamma_spline m_gamma_spline; double m_border_width; double m_border_extra; double m_curve_width; double m_grid_width; double m_text_thickness; double m_point_size; double m_text_height; double m_text_width; double m_xc1; double m_yc1; double m_xc2; double m_yc2; double m_xs1; double m_ys1; double m_xs2; double m_ys2; double m_xt1; double m_yt1; double m_xt2; double m_yt2; conv_stroke m_curve_poly; ellipse m_ellipse; gsv_text m_text; conv_stroke m_text_poly; unsigned m_idx; unsigned m_vertex; double m_vx[32]; double m_vy[32]; double m_xp1; double m_yp1; double m_xp2; double m_yp2; bool m_p1_active; unsigned m_mouse_point; double m_pdx; double m_pdy; }; template class gamma_ctrl : public gamma_ctrl_impl { public: gamma_ctrl(double x1, double y1, double x2, double y2, bool flip_y=false) : gamma_ctrl_impl(x1, y1, x2, y2, flip_y), m_background_color(rgba(1.0, 1.0, 0.9)), m_border_color(rgba(0.0, 0.0, 0.0)), m_curve_color(rgba(0.0, 0.0, 0.0)), m_grid_color(rgba(0.2, 0.2, 0.0)), m_inactive_pnt_color(rgba(0.0, 0.0, 0.0)), m_active_pnt_color(rgba(1.0, 0.0, 0.0)), m_text_color(rgba(0.0, 0.0, 0.0)) { m_colors[0] = &m_background_color; m_colors[1] = &m_border_color; m_colors[2] = &m_curve_color; m_colors[3] = &m_grid_color; m_colors[4] = &m_inactive_pnt_color; m_colors[5] = &m_active_pnt_color; m_colors[6] = &m_text_color; } // Set colors void background_color(const ColorT& c) { m_background_color = c; } void border_color(const ColorT& c) { m_border_color = c; } void curve_color(const ColorT& c) { m_curve_color = c; } void grid_color(const ColorT& c) { m_grid_color = c; } void inactive_pnt_color(const ColorT& c) { m_inactive_pnt_color = c; } void active_pnt_color(const ColorT& c) { m_active_pnt_color = c; } void text_color(const ColorT& c) { m_text_color = c; } const ColorT& color(unsigned i) const { return *m_colors[i]; } private: gamma_ctrl(const gamma_ctrl&); const gamma_ctrl& operator = (const gamma_ctrl&); ColorT m_background_color; ColorT m_border_color; ColorT m_curve_color; ColorT m_grid_color; ColorT m_inactive_pnt_color; ColorT m_active_pnt_color; ColorT m_text_color; ColorT* m_colors[7]; }; } #endif aggdraw-1.3.14/agg2/include/ctrl/agg_gamma_spline.h000066400000000000000000000072561417726601400220700ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // class gamma_spline // //---------------------------------------------------------------------------- #ifndef AGG_GAMMA_SPLINE_INCLUDED #define AGG_GAMMA_SPLINE_INCLUDED #include "agg_basics.h" #include "agg_bspline.h" namespace agg { //------------------------------------------------------------------------ // Class-helper for calculation gamma-correction arrays. A gamma-correction // array is an array of 256 unsigned chars that determine the actual values // of Anti-Aliasing for each pixel coverage value from 0 to 255. If all the // values in the array are equal to its index, i.e. 0,1,2,3,... there's // no gamma-correction. Class agg::polyfill allows you to use custom // gamma-correction arrays. You can calculate it using any approach, and // class gamma_spline allows you to calculate almost any reasonable shape // of the gamma-curve with using only 4 values - kx1, ky1, kx2, ky2. // // kx2 // +----------------------------------+ // | | | . | // | | | . | ky2 // | | . ------| // | | . | // | | . | // |----------------.|----------------| // | . | | // | . | | // |-------. | | // ky1 | . | | | // | . | | | // +----------------------------------+ // kx1 // // Each value can be in range [0...2]. Value 1.0 means one quarter of the // bounding rectangle. Function values() calculates the curve by these // 4 values. After calling it one can get the gamma-array with call gamma(). // Class also supports the vertex source interface, i.e rewind() and // vertex(). It's made for convinience and used in class gamma_ctrl. // Before calling rewind/vertex one must set the bounding box // box() using pixel coordinates. //------------------------------------------------------------------------ class gamma_spline { public: gamma_spline(); void values(double kx1, double ky1, double kx2, double ky2); const unsigned char* gamma() const { return m_gamma; } double y(double x) const; void values(double* kx1, double* ky1, double* kx2, double* ky2) const; void box(double x1, double y1, double x2, double y2); void rewind(unsigned); unsigned vertex(double* x, double* y); private: unsigned char m_gamma[256]; double m_x[4]; double m_y[4]; bspline m_spline; double m_x1; double m_y1; double m_x2; double m_y2; double m_cur_x; }; } #endif aggdraw-1.3.14/agg2/include/ctrl/agg_rbox_ctrl.h000066400000000000000000000105711417726601400214240ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // classes rbox_ctrl_impl, rbox_ctrl // //---------------------------------------------------------------------------- #ifndef AGG_RBOX_CTRL_INCLUDED #define AGG_RBOX_CTRL_INCLUDED #include "agg_basics.h" #include "agg_ellipse.h" #include "agg_conv_stroke.h" #include "agg_gsv_text.h" #include "agg_trans_affine.h" #include "agg_color_rgba.h" #include "agg_ctrl.h" namespace agg { //------------------------------------------------------------------------ class rbox_ctrl_impl : public ctrl { public: ~rbox_ctrl_impl(); rbox_ctrl_impl(double x1, double y1, double x2, double y2, bool flip_y=false); void border_width(double t, double extra=0.0); void text_thickness(double t) { m_text_thickness = t; } void text_size(double h, double w=0.0); void add_item(const char* text); int cur_item() const { return m_cur_item; } void cur_item(int i) { m_cur_item = i; } virtual bool in_rect(double x, double y) const; virtual bool on_mouse_button_down(double x, double y); virtual bool on_mouse_button_up(double x, double y); virtual bool on_mouse_move(double x, double y, bool button_flag); virtual bool on_arrow_keys(bool left, bool right, bool down, bool up); // Vertex soutce interface unsigned num_paths() { return 5; }; void rewind(unsigned id); unsigned vertex(double* x, double* y); private: void calc_rbox(); double m_border_width; double m_border_extra; double m_text_thickness; double m_text_height; double m_text_width; char* m_items[32]; unsigned m_num_items; int m_cur_item; double m_xs1; double m_ys1; double m_xs2; double m_ys2; double m_vx[32]; double m_vy[32]; unsigned m_draw_item; double m_dy; ellipse m_ellipse; conv_stroke m_ellipse_poly; gsv_text m_text; conv_stroke m_text_poly; unsigned m_idx; unsigned m_vertex; }; //------------------------------------------------------------------------ template class rbox_ctrl : public rbox_ctrl_impl { public: rbox_ctrl(double x1, double y1, double x2, double y2, bool flip_y=false) : rbox_ctrl_impl(x1, y1, x2, y2, flip_y), m_background_color(rgba(1.0, 1.0, 0.9)), m_border_color(rgba(0.0, 0.0, 0.0)), m_text_color(rgba(0.0, 0.0, 0.0)), m_inactive_color(rgba(0.0, 0.0, 0.0)), m_active_color(rgba(0.4, 0.0, 0.0)) { m_colors[0] = &m_background_color; m_colors[1] = &m_border_color; m_colors[2] = &m_text_color; m_colors[3] = &m_inactive_color; m_colors[4] = &m_active_color; } void background_color(const ColorT& c) { m_background_color = c; } void border_color(const ColorT& c) { m_border_color = c; } void text_color(const ColorT& c) { m_text_color = c; } void inactive_color(const ColorT& c) { m_inactive_color = c; } void active_color(const ColorT& c) { m_active_color = c; } const ColorT& color(unsigned i) const { return *m_colors[i]; } private: rbox_ctrl(const rbox_ctrl&); const rbox_ctrl& operator = (const rbox_ctrl&); ColorT m_background_color; ColorT m_border_color; ColorT m_text_color; ColorT m_inactive_color; ColorT m_active_color; ColorT* m_colors[5]; }; } #endif aggdraw-1.3.14/agg2/include/ctrl/agg_scale_ctrl.h000066400000000000000000000102771417726601400215440ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // classes scale_ctrl_impl, scale_ctrl // //---------------------------------------------------------------------------- #ifndef AGG_SCALE_CTRL_INCLUDED #define AGG_SCALE_CTRL_INCLUDED #include "agg_basics.h" #include "agg_math.h" #include "agg_ellipse.h" #include "agg_trans_affine.h" #include "agg_color_rgba.h" #include "agg_ctrl.h" namespace agg { //------------------------------------------------------------------------ class scale_ctrl_impl : public ctrl { enum move_e { move_nothing, move_value1, move_value2, move_slider }; public: scale_ctrl_impl(double x1, double y1, double x2, double y2, bool flip_y=false); void border_thickness(double t, double extra=0.0); double min_delta() const { return m_min_d; } void min_delta(double d) { m_min_d = d; } double value1() const { return m_value1; } void value1(double value) { m_value1 = value; } double value2() const { return m_value2; } void value2(double value) { m_value2 = value; } virtual bool in_rect(double x, double y) const; virtual bool on_mouse_button_down(double x, double y); virtual bool on_mouse_button_up(double x, double y); virtual bool on_mouse_move(double x, double y, bool button_flag); virtual bool on_arrow_keys(bool left, bool right, bool down, bool up); // Vertex soutce interface unsigned num_paths() { return 5; }; void rewind(unsigned id); unsigned vertex(double* x, double* y); private: void calc_box(); double m_border_thickness; double m_border_extra; double m_value1; double m_value2; double m_min_d; double m_xs1; double m_ys1; double m_xs2; double m_ys2; double m_pdx; move_e m_move_what; double m_vx[32]; double m_vy[32]; ellipse m_ellipse; unsigned m_idx; unsigned m_vertex; }; //------------------------------------------------------------------------ template class scale_ctrl : public scale_ctrl_impl { public: scale_ctrl(double x1, double y1, double x2, double y2, bool flip_y=false) : scale_ctrl_impl(x1, y1, x2, y2, flip_y), m_background_color(rgba(1.0, 0.9, 0.8)), m_border_color(rgba(0.0, 0.0, 0.0)), m_pointers_color(rgba(0.8, 0.0, 0.0, 0.8)), m_slider_color(rgba(0.2, 0.1, 0.0, 0.8)) { m_colors[0] = &m_background_color; m_colors[1] = &m_border_color; m_colors[2] = &m_pointers_color; m_colors[3] = &m_pointers_color; m_colors[4] = &m_slider_color; } void background_color(const ColorT& c) { m_background_color = c; } void border_color(const ColorT& c) { m_border_color = c; } void pointers_color(const ColorT& c) { m_pointers_color = c; } void slider_color(const ColorT& c) { m_slider_color = c; } const ColorT& color(unsigned i) const { return *m_colors[i]; } private: scale_ctrl(const scale_ctrl&); const scale_ctrl& operator = (const scale_ctrl&); ColorT m_background_color; ColorT m_border_color; ColorT m_pointers_color; ColorT m_slider_color; ColorT* m_colors[5]; }; } #endif aggdraw-1.3.14/agg2/include/ctrl/agg_slider_ctrl.h000066400000000000000000000111141417726601400217260ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // classes slider_ctrl_impl, slider_ctrl // //---------------------------------------------------------------------------- #ifndef AGG_SLIDER_CTRL_INCLUDED #define AGG_SLIDER_CTRL_INCLUDED #include "agg_basics.h" #include "agg_math.h" #include "agg_ellipse.h" #include "agg_trans_affine.h" #include "agg_color_rgba.h" #include "agg_gsv_text.h" #include "agg_conv_stroke.h" #include "agg_path_storage.h" #include "agg_ctrl.h" namespace agg { //--------------------------------------------------------slider_ctrl_impl class slider_ctrl_impl : public ctrl { public: slider_ctrl_impl(double x1, double y1, double x2, double y2, bool flip_y=false); void border_width(double t, double extra=0.0); void range(double min, double max) { m_min = min; m_max = max; } void num_steps(unsigned num) { m_num_steps = num; } void label(const char* fmt); void text_thickness(double t) { m_text_thickness = t; } bool descending() const { return m_descending; } void descending(bool v) { m_descending = v; } double value() const { return m_value * (m_max - m_min) + m_min; } void value(double value); virtual bool in_rect(double x, double y) const; virtual bool on_mouse_button_down(double x, double y); virtual bool on_mouse_button_up(double x, double y); virtual bool on_mouse_move(double x, double y, bool button_flag); virtual bool on_arrow_keys(bool left, bool right, bool down, bool up); // Vertex source interface unsigned num_paths() { return 6; }; void rewind(unsigned id); unsigned vertex(double* x, double* y); private: void calc_box(); bool normalize_value(bool preview_value_flag); double m_border_width; double m_border_extra; double m_text_thickness; double m_value; double m_preview_value; double m_min; double m_max; unsigned m_num_steps; bool m_descending; char m_label[64]; double m_xs1; double m_ys1; double m_xs2; double m_ys2; double m_pdx; bool m_mouse_move; double m_vx[32]; double m_vy[32]; ellipse m_ellipse; unsigned m_idx; unsigned m_vertex; gsv_text m_text; conv_stroke m_text_poly; path_storage m_storage; }; //----------------------------------------------------------slider_ctrl template class slider_ctrl : public slider_ctrl_impl { public: slider_ctrl(double x1, double y1, double x2, double y2, bool flip_y=false) : slider_ctrl_impl(x1, y1, x2, y2, flip_y), m_background_color(rgba(1.0, 0.9, 0.8)), m_triangle_color(rgba(0.7, 0.6, 0.6)), m_text_color(rgba(0.0, 0.0, 0.0)), m_pointer_preview_color(rgba(0.6, 0.4, 0.4, 0.4)), m_pointer_color(rgba(0.8, 0.0, 0.0, 0.6)) { m_colors[0] = &m_background_color; m_colors[1] = &m_triangle_color; m_colors[2] = &m_text_color; m_colors[3] = &m_pointer_preview_color; m_colors[4] = &m_pointer_color; m_colors[5] = &m_text_color; } void background_color(const ColorT& c) { m_background_color = c; } void pointer_color(const ColorT& c) { m_pointer_color = c; } const ColorT& color(unsigned i) const { return *m_colors[i]; } private: slider_ctrl(const slider_ctrl&); const slider_ctrl& operator = (const slider_ctrl&); ColorT m_background_color; ColorT m_triangle_color; ColorT m_text_color; ColorT m_pointer_preview_color; ColorT m_pointer_color; ColorT* m_colors[6]; }; } #endif aggdraw-1.3.14/agg2/include/ctrl/agg_spline_ctrl.h000066400000000000000000000131441417726601400217430ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // classes spline_ctrl_impl, spline_ctrl // //---------------------------------------------------------------------------- #ifndef AGG_SPLINE_CTRL_INCLUDED #define AGG_SPLINE_CTRL_INCLUDED #include "agg_basics.h" #include "agg_ellipse.h" #include "agg_bspline.h" #include "agg_conv_stroke.h" #include "agg_path_storage.h" #include "agg_trans_affine.h" #include "agg_color_rgba.h" #include "agg_ctrl.h" namespace agg { //------------------------------------------------------------------------ // Class that can be used to create an interactive control to set up // gamma arrays. //------------------------------------------------------------------------ class spline_ctrl_impl : public ctrl { public: spline_ctrl_impl(double x1, double y1, double x2, double y2, unsigned num_pnt, bool flip_y=false); // Set other parameters void border_width(double t, double extra=0.0); void curve_width(double t) { m_curve_width = t; } void point_size(double s) { m_point_size = s; } // Event handlers. Just call them if the respective events // in your system occure. The functions return true if redrawing // is required. virtual bool in_rect(double x, double y) const; virtual bool on_mouse_button_down(double x, double y); virtual bool on_mouse_button_up(double x, double y); virtual bool on_mouse_move(double x, double y, bool button_flag); virtual bool on_arrow_keys(bool left, bool right, bool down, bool up); void active_point(int i); const double* spline() const { return m_spline_values; } const unsigned char* spline8() const { return m_spline_values8; } double value(double x) const; void value(unsigned idx, double y); void point(unsigned idx, double x, double y); void x(unsigned idx, double x) { m_xp[idx] = x; } void y(unsigned idx, double y) { m_yp[idx] = y; } double x(unsigned idx) const { return m_xp[idx]; } double y(unsigned idx) const { return m_yp[idx]; } void update_spline(); // Vertex soutce interface unsigned num_paths() { return 5; } void rewind(unsigned id); unsigned vertex(double* x, double* y); private: void calc_spline_box(); void calc_curve(); double calc_xp(unsigned idx); double calc_yp(unsigned idx); void set_xp(unsigned idx, double val); void set_yp(unsigned idx, double val); unsigned m_num_pnt; double m_xp[32]; double m_yp[32]; bspline m_spline; double m_spline_values[256]; unsigned char m_spline_values8[256]; double m_border_width; double m_border_extra; double m_curve_width; double m_point_size; double m_xs1; double m_ys1; double m_xs2; double m_ys2; path_storage m_curve_pnt; conv_stroke m_curve_poly; ellipse m_ellipse; unsigned m_idx; unsigned m_vertex; double m_vx[32]; double m_vy[32]; int m_active_pnt; int m_move_pnt; double m_pdx; double m_pdy; const trans_affine* m_mtx; }; template class spline_ctrl : public spline_ctrl_impl { public: spline_ctrl(double x1, double y1, double x2, double y2, unsigned num_pnt, bool flip_y=false) : spline_ctrl_impl(x1, y1, x2, y2, num_pnt, flip_y), m_background_color(rgba(1.0, 1.0, 0.9)), m_border_color(rgba(0.0, 0.0, 0.0)), m_curve_color(rgba(0.0, 0.0, 0.0)), m_inactive_pnt_color(rgba(0.0, 0.0, 0.0)), m_active_pnt_color(rgba(1.0, 0.0, 0.0)) { m_colors[0] = &m_background_color; m_colors[1] = &m_border_color; m_colors[2] = &m_curve_color; m_colors[3] = &m_inactive_pnt_color; m_colors[4] = &m_active_pnt_color; } // Set colors void background_color(const ColorT& c) { m_background_color = c; } void border_color(const ColorT& c) { m_border_color = c; } void curve_color(const ColorT& c) { m_curve_color = c; } void inactive_pnt_color(const ColorT& c) { m_inactive_pnt_color = c; } void active_pnt_color(const ColorT& c) { m_active_pnt_color = c; } const ColorT& color(unsigned i) const { return *m_colors[i]; } private: spline_ctrl(const spline_ctrl&); const spline_ctrl& operator = (const spline_ctrl&); ColorT m_background_color; ColorT m_border_color; ColorT m_curve_color; ColorT m_inactive_pnt_color; ColorT m_active_pnt_color; ColorT* m_colors[5]; }; } #endif aggdraw-1.3.14/agg2/include/dbg_new/000077500000000000000000000000001417726601400170745ustar00rootroot00000000000000aggdraw-1.3.14/agg2/include/dbg_new/agg_dbg_new.h000066400000000000000000000044771417726601400215040ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Debuging stuff for catching memory leaks and corruptions // //---------------------------------------------------------------------------- #ifndef AGG_DBG_NEW_INCLUDED #define AGG_DBG_NEW_INCLUDED #ifdef _WIN32 #include #include #endif //#define AGG_DBG_NEW_CHECK_ADDR void* operator new (unsigned size, const char* file, int line); void* operator new [] (unsigned size, const char* file, int line); #define AGG_DBG_NEW_OPERATOR new(__FILE__, __LINE__) void operator delete(void *ptr) throw(); void operator delete [] (void *ptr) throw(); namespace agg { #ifdef _WIN32 inline void printf(char* fmt, ...) { FILE* fd = fopen("stdout.txt", "at"); static char msg[1024]; va_list arg; va_start(arg, fmt); vsprintf(msg, fmt, arg); va_end(arg); fputs(msg, fd); fclose(fd); } #endif enum { max_dbg_new_level = 32 }; #ifdef AGG_DBG_NEW_CHECK_ADDR enum { max_allocations = 4096 }; #endif // All you need to watch for memory in heap is to declare an object // of this class in your main() or whatever function you need. // It will report you about all bad things happend to new/delete. // Try not to exceed the maximal nested level of declared watchdoggies // (max_dbg_new_level) class watchdoggy { public: watchdoggy(const char* file=0, int line=0, bool report_all=false); ~watchdoggy(); }; } #define AGG_WATCHDOGGY(name, report_all) \ agg::watchdoggy name(__FILE__, __LINE__, report_all); #endif #ifdef new #undef new #endif #define new AGG_DBG_NEW_OPERATOR aggdraw-1.3.14/agg2/include/platform/000077500000000000000000000000001417726601400173135ustar00rootroot00000000000000aggdraw-1.3.14/agg2/include/platform/agg_platform_support.h000066400000000000000000000665021417726601400237330ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // class platform_support // // It's not a part of the AGG library, it's just a helper class to create // interactive demo examples. Since the examples should not be too complex // this class is provided to support some very basic interactive graphical // funtionality, such as putting the rendered image to the window, simple // keyboard and mouse input, window resizing, setting the window title, // and catching the "idle" events. // // The idea is to have a single header file that does not depend on any // platform (I hate these endless #ifdef/#elif/#elif.../#endif) and a number // of different implementations depending on the concrete platform. // The most popular platforms are: // // Windows-32 API // X-Window API // SDL library (see http://www.libsdl.org/) // MacOS C/C++ API // // This file does not include any system dependent .h files such as // windows.h or X11.h, so, your demo applications do not depend on the // platform. The only file that can #include system dependend headers // is the implementation file agg_platform_support.cpp. Different // implementations are placed in different directories, such as // ~/agg/src/platform/win32 // ~/agg/src/platform/sdl // ~/agg/src/platform/X11 // and so on. // // All the system dependent stuff sits in the platform_specific // class which is forward-declared here but not defined. // The platform_support class has just a pointer to it and it's // the responsibility of the implementation to create/delete it. // This class being defined in the implementation file can have // any platform dependent stuff such as HWND, X11 Window and so on. // //---------------------------------------------------------------------------- #ifndef AGG_PLATFORM_SUPPORT_INCLUDED #define AGG_PLATFORM_SUPPORT_INCLUDED #include "agg_basics.h" #include "agg_rendering_buffer.h" #include "agg_trans_affine.h" #include "ctrl/agg_ctrl.h" namespace agg { //----------------------------------------------------------window_flag_e // These are flags used in method init(). Not all of them are // applicable on different platforms, for example the win32_api // cannot use a hardware buffer (window_hw_buffer). // The implementation should simply ignore unsupported flags. enum window_flag_e { window_resize = 1, window_hw_buffer = 2, window_keep_aspect_ratio = 4 }; //-----------------------------------------------------------pix_format_e // Possible formats of the rendering buffer. Initially I thought that it's // reasonable to create the buffer and the rendering functions in // accordance with the native pixel format of the system because it // would have no overhead for pixel format conersion. // But eventually I came to a conclusion that having a possibility to // convert pixel formats on demand is a good idea. First, it was X11 where // there lots of different formats and visuals and it would be great to // render everything in, say, RGB-24 and display it automatically without // any additional efforts. The second reason is to have a possibility to // debug renderers for different pixel formats and colorspaces having only // one computer and one system. // // This stuff is not included into the basic AGG functionality because the // number of supported pixel formats (and/or colorspaces) can be great and // if one needs to add new format it would be good only to add new // rendering files without having to modify any existing ones (a general // principle of incapsulation and isolation). // // Using a particular pixel format doesn't obligatory mean the necessity // of software conversion. For example, win32 API can natively display // gray8, 15-bit RGB, 24-bit BGR, and 32-bit BGRA formats. // This list can be (and will be!) extended in future. enum pix_format_e { pix_format_undefined = 0, // By default. No conversions are applied pix_format_gray8, // Simple 256 level grayscale pix_format_rgb555, // 15 bit rgb. Depends on the byte ordering! pix_format_rgb565, // 16 bit rgb. Depends on the byte ordering! pix_format_rgb24, // R-G-B, one byte per color component pix_format_bgr24, // B-G-R, native win32 BMP format. pix_format_rgba32, // R-G-B-A, one byte per color component pix_format_argb32, // A-R-G-B, native MAC format pix_format_abgr32, // A-B-G-R, one byte per color component pix_format_bgra32, // B-G-R-A, native win32 BMP format end_of_pix_formats }; //-------------------------------------------------------------input_flag_e // Mouse and keyboard flags. They can be different on different platforms // and the ways they are obtained are also different. But in any case // the system dependent flags should be mapped into these ones. The meaning // of that is as follows. For example, if kbd_ctrl is set it means that the // ctrl key is pressed and being held at the moment. They are also used in // the overridden methods such as on_mouse_move(), on_mouse_button_down(), // on_mouse_button_dbl_click(), on_mouse_button_up(), on_key(). // In the method on_mouse_button_up() the mouse flags have different // meaning. They mean that the respective button is being released, but // the meaning of the keyboard flags remains the same. // There's absolut minimal set of flags is used because they'll be most // probably supported on different platforms. Even the mouse_right flag // is restricted because Mac's mice have only one button, but AFAIK // it can be simulated with holding a special key on the keydoard. enum input_flag_e { mouse_left = 1, mouse_right = 2, kbd_shift = 4, kbd_ctrl = 8 }; //--------------------------------------------------------------key_code_e // Keyboard codes. There's also a restricted set of codes that are most // probably supported on different platforms. Any platform dependent codes // should be converted into these ones. There're only those codes are // defined that cannot be represented as printable ASCII-characters. // All printable ASCII-set can be used in a regilar C/C++ manner: // ' ', 'A', '0' '+' and so on. // Since the clasas is used for creating very simple demo-applications // we don't need very rich possibilities here, just basic ones. // Actually the numeric key codes are taken from the SDL library, so, // the implementation of the SDL support does not require any mapping. enum key_code_e { // ASCII set. Should be supported everywhere key_backspace = 8, key_tab = 9, key_clear = 12, key_return = 13, key_pause = 19, key_escape = 27, // Keypad key_delete = 127, key_kp0 = 256, key_kp1 = 257, key_kp2 = 258, key_kp3 = 259, key_kp4 = 260, key_kp5 = 261, key_kp6 = 262, key_kp7 = 263, key_kp8 = 264, key_kp9 = 265, key_kp_period = 266, key_kp_divide = 267, key_kp_multiply = 268, key_kp_minus = 269, key_kp_plus = 270, key_kp_enter = 271, key_kp_equals = 272, // Arrow-keys and stuff key_up = 273, key_down = 274, key_right = 275, key_left = 276, key_insert = 277, key_home = 278, key_end = 279, key_page_up = 280, key_page_down = 281, // Functional keys. You'd better avoid using // f11...f15 in your applications if you want // the applications to be portable key_f1 = 282, key_f2 = 283, key_f3 = 284, key_f4 = 285, key_f5 = 286, key_f6 = 287, key_f7 = 288, key_f8 = 289, key_f9 = 290, key_f10 = 291, key_f11 = 292, key_f12 = 293, key_f13 = 294, key_f14 = 295, key_f15 = 296, // The possibility of using these keys is // very restricted. Actually it's guaranteed // only in win32_api and win32_sdl implementations key_numlock = 300, key_capslock = 301, key_scrollock = 302, // Phew! end_of_key_codes }; //------------------------------------------------------------------------ // A predeclaration of the platform dependent class. Since we do not // know anything here the only we can have is just a pointer to this // class as a data member. It should be created and destroyed explicitely // in the constructor/destructor of the platform_support class. // Although the pointer to platform_specific is public the application // cannot have access to its members or methods since it does not know // anything about them and it's a perfect incapsulation :-) class platform_specific; //----------------------------------------------------------ctrl_container // A helper class that contains pointers to a number of controls. // This class is used to ease the event handling with controls. // The implementation should simply call the appropriate methods // of this class when appropriate events occure. class ctrl_container { enum { max_ctrl = 64 }; public: //-------------------------------------------------------------------- ctrl_container() : m_num_ctrl(0), m_cur_ctrl(-1) {} //-------------------------------------------------------------------- void add(ctrl& c) { if(m_num_ctrl < max_ctrl) { m_ctrl[m_num_ctrl++] = &c; } } //-------------------------------------------------------------------- bool in_rect(double x, double y) { unsigned i; for(i = 0; i < m_num_ctrl; i++) { if(m_ctrl[i]->in_rect(x, y)) return true; } return false; } //-------------------------------------------------------------------- bool on_mouse_button_down(double x, double y) { unsigned i; for(i = 0; i < m_num_ctrl; i++) { if(m_ctrl[i]->on_mouse_button_down(x, y)) return true; } return false; } //-------------------------------------------------------------------- bool on_mouse_button_up(double x, double y) { unsigned i; bool flag = false; for(i = 0; i < m_num_ctrl; i++) { if(m_ctrl[i]->on_mouse_button_up(x, y)) flag = true; } return flag; } //-------------------------------------------------------------------- bool on_mouse_move(double x, double y, bool button_flag) { unsigned i; for(i = 0; i < m_num_ctrl; i++) { if(m_ctrl[i]->on_mouse_move(x, y, button_flag)) return true; } return false; } //-------------------------------------------------------------------- bool on_arrow_keys(bool left, bool right, bool down, bool up) { if(m_cur_ctrl >= 0) { return m_ctrl[m_cur_ctrl]->on_arrow_keys(left, right, down, up); } return false; } //-------------------------------------------------------------------- bool set_cur(double x, double y) { unsigned i; for(i = 0; i < m_num_ctrl; i++) { if(m_ctrl[i]->in_rect(x, y)) { if(m_cur_ctrl != int(i)) { m_cur_ctrl = i; return true; } return false; } } if(m_cur_ctrl != -1) { m_cur_ctrl = -1; return true; } return false; } private: ctrl* m_ctrl[max_ctrl]; unsigned m_num_ctrl; int m_cur_ctrl; }; //---------------------------------------------------------platform_support // This class is a base one to the apllication classes. It can be used // as follows: // // class the_application : public agg::platform_support // { // public: // the_application(unsigned bpp, bool flip_y) : // platform_support(bpp, flip_y) // . . . // // //override stuff . . . // virtual void on_init() // { // . . . // } // // virtual void on_draw() // { // . . . // } // // virtual void on_resize(int sx, int sy) // { // . . . // } // // . . . and so on, see virtual functions // // // //any your own stuff . . . // }; // // // int agg_main(int argc, char* argv[]) // { // the_application app(pix_format_rgb24, true); // app.caption("AGG Example. Lion"); // // if(app.init(500, 400, agg::window_resize)) // { // return app.run(); // } // return 1; // } // // The reason to have agg_main() instead of just main() is that SDL // for Windows requires including SDL.h if you define main(). Since // the demo applications cannot rely on any platform/library specific // stuff it's impossible to include SDL.h into the application files. // The demo applications are simple and their use is restricted, so, // this approach is quite reasonable. // class platform_support { public: enum { max_images = 16 }; // format - see enum pix_format_e {}; // flip_y - true if you want to have the Y-axis flipped vertically. platform_support(pix_format_e format, bool flip_y); virtual ~platform_support(); // Setting the windows caption (title). Should be able // to be called at least before calling init(). // It's perfect if they can be called anytime. void caption(const char* cap); const char* caption() const { return m_caption; } //-------------------------------------------------------------------- // These 3 menthods handle working with images. The image // formats are the simplest ones, such as .BMP in Windows or // .ppm in Linux. In the applications the names of the files // should not have any file extensions. Method load_img() can // be called before init(), so, the application could be able // to determine the initial size of the window depending on // the size of the loaded image. // The argument "idx" is the number of the image 0...max_images-1 bool load_img(unsigned idx, const char* file); bool save_img(unsigned idx, const char* file); bool create_img(unsigned idx, unsigned width=0, unsigned height=0); //-------------------------------------------------------------------- // init() and run(). See description before the class for details. // The necessity of calling init() after creation is that it's // impossible to call the overridden virtual function (on_init()) // from the constructor. On the other hand it's very useful to have // some on_init() event handler when the window is created but // not yet displayed. The rbuf_window() method (see below) is // accessible from on_init(). bool init(unsigned width, unsigned height, unsigned flags); int run(); //-------------------------------------------------------------------- // The very same parameters that were used in the constructor pix_format_e format() const { return m_format; } bool flip_y() const { return m_flip_y; } unsigned bpp() const { return m_bpp; } //-------------------------------------------------------------------- // The following provides a very simple mechanism of doing someting // in background. It's not multitheading. When whait_mode is true // the class waits for the events and it does not ever call on_idle(). // When it's false it calls on_idle() when the event queue is empty. // The mode can be changed anytime. This mechanism is satisfactory // for creation very simple animations. bool wait_mode() const { return m_wait_mode; } void wait_mode(bool wait_mode) { m_wait_mode = wait_mode; } //-------------------------------------------------------------------- // These two functions control updating of the window. // force_redraw() is an analog of the Win32 InvalidateRect() function. // Being called it sets a flag (or sends a message) which results // in calling on_draw() and updating the content of the window // when the next event cycle comes. // update_window() results in just putting immediately the content // of the currently rendered buffer to the window without calling // on_draw(). void force_redraw(); void update_window(); //-------------------------------------------------------------------- // So, finally, how to draw anythig with AGG? Very simple. // rbuf_window() returns a reference to the main rendering // buffer which can be attached to any rendering class. // rbuf_img() returns a reference to the previously created // or loaded image buffer (see load_img()). The image buffers // are not displayed directly, they should be copied to or // combined somehow with the rbuf_window(). rbuf_window() is // the only buffer that can be actually displayed. rendering_buffer& rbuf_window() { return m_rbuf_window; } rendering_buffer& rbuf_img(unsigned idx) { return m_rbuf_img[idx]; } //-------------------------------------------------------------------- // Returns file extension used in the implemenation for the particular // system. const char* img_ext() const; //-------------------------------------------------------------------- void copy_img_to_window(unsigned idx) { if(idx < max_images && rbuf_img(idx).buf()) { rbuf_window().copy_from(rbuf_img(idx)); } } //-------------------------------------------------------------------- void copy_window_to_img(unsigned idx) { if(idx < max_images) { create_img(idx, rbuf_window().width(), rbuf_window().height()); rbuf_img(idx).copy_from(rbuf_window()); } } //-------------------------------------------------------------------- void copy_img_to_img(unsigned idx_to, unsigned idx_from) { if(idx_from < max_images && idx_to < max_images && rbuf_img(idx_from).buf()) { create_img(idx_to, rbuf_img(idx_from).width(), rbuf_img(idx_from).height()); rbuf_img(idx_to).copy_from(rbuf_img(idx_from)); } } //-------------------------------------------------------------------- // Event handlers. They are not pure functions, so you don't have // to override them all. // In my demo applications these functions are defined inside // the the_application class (implicit inlining) which is in general // very bad practice, I mean vitual inline methods. At least it does // not make sence. // But in this case it's quite appropriate bacause we have the only // instance of the the_application class and it is in the same file // where this class is defined. virtual void on_init(); virtual void on_resize(int sx, int sy); virtual void on_idle(); virtual void on_mouse_move(int x, int y, unsigned flags); virtual void on_mouse_button_down(int x, int y, unsigned flags); virtual void on_mouse_button_up(int x, int y, unsigned flags); virtual void on_key(int x, int y, unsigned key, unsigned flags); virtual void on_ctrl_change(); virtual void on_draw(); virtual void on_post_draw(void* raw_handler); //-------------------------------------------------------------------- // Adding control elements. A control element once added will be // working and reacting to the mouse and keyboard events. Still, you // will have to render them in the on_draw() using function // render_ctrl() because platform_support doesn't know anything about // renderers you use. The controls will be also scaled automatically // if they provide a proper scaling mechanism (all the controls // included into the basic AGG package do). // If you don't need a particular control to be scaled automatically // call ctrl::no_transform() after adding. void add_ctrl(ctrl& c) { m_ctrls.add(c); c.transform(m_resize_mtx); } //-------------------------------------------------------------------- // Auxiliary functions. trans_affine_resizing() modifier sets up the resizing // matrix on the basis of the given width and height and the initial // width and height of the window. The implementation should simply // call this function every time when it catches the resizing event // passing in the new values of width and height of the window. // Nothing prevents you from "cheating" the scaling matrix if you // call this function from somewhere with wrong arguments. // trans_affine_resizing() accessor simply returns current resizing matrix // which can be used to apply additional scaling of any of your // stuff when the window is being resized. // width(), height(), initial_width(), and initial_height() must be // clear to understand with no comments :-) void trans_affine_resizing(int width, int height) { if(m_window_flags & window_keep_aspect_ratio) { double sx = double(width) / double(m_initial_width); double sy = double(height) / double(m_initial_height); if(sy < sx) sx = sy; m_resize_mtx = trans_affine_scaling(sx, sx); } else { m_resize_mtx = trans_affine_scaling( double(width) / double(m_initial_width), double(height) / double(m_initial_height)); } } const trans_affine& trans_affine_resizing() const { return m_resize_mtx; } double width() const { return m_rbuf_window.width(); } double height() const { return m_rbuf_window.height(); } double initial_width() const { return m_initial_width; } double initial_height() const { return m_initial_height; } //-------------------------------------------------------------------- // Get raw display handler depending on the system. // For win32 its an HDC, for other systems it can be a pointer to some // structure. See the implementation files for detals. // It's provided "as is", so, first you should check if it's not null. // If it's null the raw_display_handler is not supported. Also, there's // no guarantee that this function is implemented, so, in some // implementations you may have simply an unresolved symbol when linking. void* raw_display_handler(); //-------------------------------------------------------------------- // display message box or print the message to the console // (depending on implementation) void message(const char* msg); //-------------------------------------------------------------------- // Stopwatch functions. Function elapsed_time() returns time elapsed // since the latest start_timer() invocation in millisecods. // The resolutoin depends on the implementation. // In Win32 it uses QueryPerformanceFrequency() / QueryPerformanceCounter(). void start_timer(); double elapsed_time() const; //-------------------------------------------------------------------- // Get the full file name. In most cases it simply returns // file_name. As it's appropriate in many systems if you open // a file by its name without specifying the path, it tries to // open it in the current directory. The demos usually expect // all the supplementary files to be placed in the current // directory, that is usually coincides with the directory where // the the executable is. However, in some systems (BeOS) it's not so. // For those kinds of systems full_file_name() can help access files // preserving commonly used policy. // So, it's a good idea to use in the demos the following: // FILE* fd = fopen(full_file_name("some.file"), "r"); // instead of // FILE* fd = fopen("some.file", "r"); const char* full_file_name(const char* file_name); public: platform_specific* m_specific; ctrl_container m_ctrls; // Sorry, I'm too tired to descibe the private // data membders. See the implementations for different // platforms for details. private: platform_support(const platform_support&); const platform_support& operator = (const platform_support&); pix_format_e m_format; unsigned m_bpp; rendering_buffer m_rbuf_window; rendering_buffer m_rbuf_img[max_images]; unsigned m_window_flags; bool m_wait_mode; bool m_flip_y; char m_caption[256]; int m_initial_width; int m_initial_height; trans_affine m_resize_mtx; }; } #endif aggdraw-1.3.14/agg2/include/platform/mac/000077500000000000000000000000001417726601400200535ustar00rootroot00000000000000aggdraw-1.3.14/agg2/include/platform/mac/agg_mac_pmap.h000066400000000000000000000051631417726601400226240ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.0 // Copyright (C) 2002 Maxim Shemanarev (McSeem) // Copyright (C) 2002 Hansruedi Baer (MacOS support) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com // baer@karto.baug.eth.ch //---------------------------------------------------------------------------- // // class pixel_map // //---------------------------------------------------------------------------- #ifndef AGG_MAC_PMAP_INCLUDED #define AGG_MAC_PMAP_INCLUDED #include #include namespace agg { enum org_e { org_mono8 = 8, org_color16 = 16, org_color24 = 24, org_color32 = 32 }; class pixel_map { public: ~pixel_map(); pixel_map(); public: void destroy(); void create(unsigned width, unsigned height, org_e org, unsigned clear_val=255); void clear(unsigned clear_val=255); bool load_from_qt(const char* filename); bool save_as_qt(const char* filename) const; void draw(WindowRef window, const Rect* device_rect=0, const Rect* bmp_rect=0) const; void draw(WindowRef window, int x, int y, double scale=1.0) const; void blend(WindowRef window, const Rect* device_rect=0, const Rect* bmp_rect=0) const; void blend(WindowRef window, int x, int y, double scale=1.0) const; unsigned char* buf(); unsigned width() const; unsigned height() const; int row_bytes() const; unsigned bpp() const { return m_bpp; } //Auxiliary static functions static unsigned calc_row_len(unsigned width, unsigned bits_per_pixel); private: pixel_map(const pixel_map&); const pixel_map& operator = (const pixel_map&); private: GWorldPtr m_pmap; unsigned char* m_buf; unsigned m_bpp; unsigned m_img_size; }; } #endif aggdraw-1.3.14/agg2/include/platform/win32/000077500000000000000000000000001417726601400202555ustar00rootroot00000000000000aggdraw-1.3.14/agg2/include/platform/win32/agg_win32_bmp.h000066400000000000000000000067351417726601400230570ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // class pixel_map // //---------------------------------------------------------------------------- #ifndef AGG_WIN32_BMP_INCLUDED #define AGG_WIN32_BMP_INCLUDED #include #include namespace agg { enum org_e { org_mono8 = 8, org_color16 = 16, org_color24 = 24, org_color32 = 32 }; class pixel_map { public: ~pixel_map(); pixel_map(); public: void destroy(); void create(unsigned width, unsigned height, org_e org, unsigned clear_val=256); void clear(unsigned clear_val=256); void attach_to_bmp(BITMAPINFO* bmp); BITMAPINFO* bitmap_info() { return m_bmp; } bool load_from_bmp(FILE* fd); bool save_as_bmp(FILE* fd) const; bool load_from_bmp(const char* filename); bool save_as_bmp(const char* filename) const; void draw(HDC h_dc, const RECT* device_rect=0, const RECT* bmp_rect=0) const; void draw(HDC h_dc, int x, int y, double scale=1.0) const; void blend(HDC h_dc, const RECT* device_rect=0, const RECT* bmp_rect=0) const; void blend(HDC h_dc, int x, int y, double scale=1.0) const; unsigned char* buf(); unsigned width() const; unsigned height() const; int stride() const; unsigned bpp() const { return m_bpp; } //Auxiliary static functions static unsigned calc_full_size(BITMAPINFO *bmp); static unsigned calc_header_size(BITMAPINFO *bmp); static unsigned calc_palette_size(unsigned clr_used, unsigned bits_per_pixel); static unsigned calc_palette_size(BITMAPINFO *bmp); static unsigned char* calc_img_ptr(BITMAPINFO *bmp); static BITMAPINFO* create_bitmap_info(unsigned width, unsigned height, unsigned bits_per_pixel); static void create_gray_scale_palette(BITMAPINFO *bmp); static unsigned calc_row_len(unsigned width, unsigned bits_per_pixel); private: pixel_map(const pixel_map&); const pixel_map& operator = (const pixel_map&); void create_from_bmp(BITMAPINFO *bmp); private: BITMAPINFO* m_bmp; unsigned char* m_buf; unsigned m_bpp; bool m_is_internal; unsigned m_img_size; unsigned m_full_size; }; } #endif aggdraw-1.3.14/agg2/include/util/000077500000000000000000000000001417726601400164445ustar00rootroot00000000000000aggdraw-1.3.14/agg2/include/util/agg_color_conv.h000066400000000000000000000045541417726601400216060ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Conversion from one colorspace/pixel format to another // //---------------------------------------------------------------------------- #ifndef AGG_COLOR_CONV_INCLUDED #define AGG_COLOR_CONV_INCLUDED #include #include "agg_basics.h" #include "agg_rendering_buffer.h" namespace agg { //--------------------------------------------------------------color_conv template void color_conv(rendering_buffer* dst, const rendering_buffer* src, CopyRow copy_row_functor) { unsigned width = src->width(); unsigned height = src->height(); if(dst->width() < width) width = dst->width(); if(dst->height() < height) height = dst->height(); if(width) { unsigned y; for(y = 0; y < height; y++) { copy_row_functor(dst->row(y), src->row(y), width); } } } //---------------------------------------------------------color_conv_row template void color_conv_row(unsigned char* dst, const unsigned char* src, unsigned width, CopyRow copy_row_functor) { copy_row_functor(dst, src, width); } //---------------------------------------------------------color_conv_same template class color_conv_same { public: void operator () (unsigned char* dst, const unsigned char* src, unsigned width) const { memmove(dst, src, width*BPP); } }; } #endif aggdraw-1.3.14/agg2/include/util/agg_color_conv_rgb8.h000066400000000000000000000420711417726601400225240ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // A set of functors used with color_conv(). See file agg_color_conv.h // These functors can convert images with up to 8 bits per component. // Use convertors in the following way: // // agg::color_conv(dst, src, agg::color_conv_XXXX_to_YYYY()); // whare XXXX and YYYY can be any of: // rgb24 // bgr24 // rgba32 // abgr32 // argb32 // bgra32 // rgb555 // rgb565 //---------------------------------------------------------------------------- #ifndef AGG_COLOR_CONV_RGB8_INCLUDED #define AGG_COLOR_CONV_RGB8_INCLUDED #include "agg_basics.h" #include "agg_color_conv.h" namespace agg { //-----------------------------------------------------color_conv_rgb24 class color_conv_rgb24 { public: void operator () (unsigned char* dst, const unsigned char* src, unsigned width) const { do { *dst++ = src[2]; *dst++ = src[1]; *dst++ = src[0]; src += 3; } while(--width); } }; typedef color_conv_rgb24 color_conv_rgb24_to_bgr24; typedef color_conv_rgb24 color_conv_bgr24_to_rgb24; typedef color_conv_same<3> color_conv_bgr24_to_bgr24; typedef color_conv_same<3> color_conv_rgb24_to_rgb24; //------------------------------------------------------color_conv_rgba32 template class color_conv_rgba32 { public: void operator () (unsigned char* dst, const unsigned char* src, unsigned width) const { do { *dst++ = src[I1]; *dst++ = src[I2]; *dst++ = src[I3]; *dst++ = src[I4]; src += 4; } while(--width); } }; //------------------------------------------------------------------------ typedef color_conv_rgba32<0,3,2,1> color_conv_argb32_to_abgr32; //----color_conv_argb32_to_abgr32 typedef color_conv_rgba32<3,2,1,0> color_conv_argb32_to_bgra32; //----color_conv_argb32_to_bgra32 typedef color_conv_rgba32<1,2,3,0> color_conv_argb32_to_rgba32; //----color_conv_argb32_to_rgba32 typedef color_conv_rgba32<3,0,1,2> color_conv_bgra32_to_abgr32; //----color_conv_bgra32_to_abgr32 typedef color_conv_rgba32<3,2,1,0> color_conv_bgra32_to_argb32; //----color_conv_bgra32_to_argb32 typedef color_conv_rgba32<2,1,0,3> color_conv_bgra32_to_rgba32; //----color_conv_bgra32_to_rgba32 typedef color_conv_rgba32<3,2,1,0> color_conv_rgba32_to_abgr32; //----color_conv_rgba32_to_abgr32 typedef color_conv_rgba32<3,0,1,2> color_conv_rgba32_to_argb32; //----color_conv_rgba32_to_argb32 typedef color_conv_rgba32<2,1,0,3> color_conv_rgba32_to_bgra32; //----color_conv_rgba32_to_bgra32 typedef color_conv_rgba32<0,3,2,1> color_conv_abgr32_to_argb32; //----color_conv_abgr32_to_argb32 typedef color_conv_rgba32<1,2,3,0> color_conv_abgr32_to_bgra32; //----color_conv_abgr32_to_bgra32 typedef color_conv_rgba32<3,2,1,0> color_conv_abgr32_to_rgba32; //----color_conv_abgr32_to_rgba32 //------------------------------------------------------------------------ typedef color_conv_same<4> color_conv_rgba32_to_rgba32; //----color_conv_rgba32_to_rgba32 typedef color_conv_same<4> color_conv_argb32_to_argb32; //----color_conv_argb32_to_argb32 typedef color_conv_same<4> color_conv_bgra32_to_bgra32; //----color_conv_bgra32_to_bgra32 typedef color_conv_same<4> color_conv_abgr32_to_abgr32; //----color_conv_abgr32_to_abgr32 //--------------------------------------------color_conv_rgb24_rgba32 template class color_conv_rgb24_rgba32 { public: void operator () (unsigned char* dst, const unsigned char* src, unsigned width) const { do { dst[I1] = *src++; dst[I2] = *src++; dst[I3] = *src++; dst[A] = 255; dst += 4; } while(--width); } }; //------------------------------------------------------------------------ typedef color_conv_rgb24_rgba32<1,2,3,0> color_conv_rgb24_to_argb32; //----color_conv_rgb24_to_argb32 typedef color_conv_rgb24_rgba32<3,2,1,0> color_conv_rgb24_to_abgr32; //----color_conv_rgb24_to_abgr32 typedef color_conv_rgb24_rgba32<2,1,0,3> color_conv_rgb24_to_bgra32; //----color_conv_rgb24_to_bgra32 typedef color_conv_rgb24_rgba32<0,1,2,3> color_conv_rgb24_to_rgba32; //----color_conv_rgb24_to_rgba32 typedef color_conv_rgb24_rgba32<3,2,1,0> color_conv_bgr24_to_argb32; //----color_conv_bgr24_to_argb32 typedef color_conv_rgb24_rgba32<1,2,3,0> color_conv_bgr24_to_abgr32; //----color_conv_bgr24_to_abgr32 typedef color_conv_rgb24_rgba32<0,1,2,3> color_conv_bgr24_to_bgra32; //----color_conv_bgr24_to_bgra32 typedef color_conv_rgb24_rgba32<2,1,0,3> color_conv_bgr24_to_rgba32; //----color_conv_bgr24_to_rgba32 //-------------------------------------------------color_conv_rgba32_rgb24 template class color_conv_rgba32_rgb24 { public: void operator () (unsigned char* dst, const unsigned char* src, unsigned width) const { do { *dst++ = src[I1]; *dst++ = src[I2]; *dst++ = src[I3]; src += 4; } while(--width); } }; //------------------------------------------------------------------------ typedef color_conv_rgba32_rgb24<1,2,3> color_conv_argb32_to_rgb24; //----color_conv_argb32_to_rgb24 typedef color_conv_rgba32_rgb24<3,2,1> color_conv_abgr32_to_rgb24; //----color_conv_abgr32_to_rgb24 typedef color_conv_rgba32_rgb24<2,1,0> color_conv_bgra32_to_rgb24; //----color_conv_bgra32_to_rgb24 typedef color_conv_rgba32_rgb24<0,1,2> color_conv_rgba32_to_rgb24; //----color_conv_rgba32_to_rgb24 typedef color_conv_rgba32_rgb24<3,2,1> color_conv_argb32_to_bgr24; //----color_conv_argb32_to_bgr24 typedef color_conv_rgba32_rgb24<1,2,3> color_conv_abgr32_to_bgr24; //----color_conv_abgr32_to_bgr24 typedef color_conv_rgba32_rgb24<0,1,2> color_conv_bgra32_to_bgr24; //----color_conv_bgra32_to_bgr24 typedef color_conv_rgba32_rgb24<2,1,0> color_conv_rgba32_to_bgr24; //----color_conv_rgba32_to_bgr24 //------------------------------------------------color_conv_rgb555_rgb24 template class color_conv_rgb555_rgb24 { public: void operator () (unsigned char* dst, const unsigned char* src, unsigned width) const { do { unsigned rgb = *(int16u*)src; dst[R] = (unsigned char)((rgb >> 7) & 0xF8); dst[1] = (unsigned char)((rgb >> 2) & 0xF8); dst[B] = (unsigned char)((rgb << 3) & 0xF8); src += 2; dst += 3; } while(--width); } }; //------------------------------------------------------------------------ typedef color_conv_rgb555_rgb24<2,0> color_conv_rgb555_to_bgr24; //----color_conv_rgb555_to_bgr24 typedef color_conv_rgb555_rgb24<0,2> color_conv_rgb555_to_rgb24; //----color_conv_rgb555_to_rgb24 //-------------------------------------------------color_conv_rgb24_rgb555 template class color_conv_rgb24_rgb555 { public: void operator () (unsigned char* dst, const unsigned char* src, unsigned width) const { do { *(int16u*)dst = (int16u)(((unsigned(src[R]) << 7) & 0x7C00) | ((unsigned(src[1]) << 2) & 0x3E0) | ((unsigned(src[B]) >> 3))); src += 3; dst += 2; } while(--width); } }; //------------------------------------------------------------------------ typedef color_conv_rgb24_rgb555<2,0> color_conv_bgr24_to_rgb555; //----color_conv_bgr24_to_rgb555 typedef color_conv_rgb24_rgb555<0,2> color_conv_rgb24_to_rgb555; //----color_conv_rgb24_to_rgb555 //-------------------------------------------------color_conv_rgb565_rgb24 template class color_conv_rgb565_rgb24 { public: void operator () (unsigned char* dst, const unsigned char* src, unsigned width) const { do { unsigned rgb = *(int16u*)src; dst[R] = (rgb >> 8) & 0xF8; dst[1] = (rgb >> 3) & 0xFC; dst[B] = (rgb << 3) & 0xF8; src += 2; dst += 3; } while(--width); } }; //------------------------------------------------------------------------ typedef color_conv_rgb565_rgb24<2,0> color_conv_rgb565_to_bgr24; //----color_conv_rgb565_to_bgr24 typedef color_conv_rgb565_rgb24<0,2> color_conv_rgb565_to_rgb24; //----color_conv_rgb565_to_rgb24 //-------------------------------------------------color_conv_rgb24_rgb565 template class color_conv_rgb24_rgb565 { public: void operator () (unsigned char* dst, const unsigned char* src, unsigned width) const { do { *(int16u*)dst = (int16u)(((unsigned(src[R]) << 8) & 0xF800) | ((unsigned(src[1]) << 3) & 0x7E0) | ((unsigned(src[B]) >> 3))); src += 3; dst += 2; } while(--width); } }; //------------------------------------------------------------------------ typedef color_conv_rgb24_rgb565<2,0> color_conv_bgr24_to_rgb565; //----color_conv_bgr24_to_rgb565 typedef color_conv_rgb24_rgb565<0,2> color_conv_rgb24_to_rgb565; //----color_conv_rgb24_to_rgb565 //-------------------------------------------------color_conv_rgb555_rgba32 template class color_conv_rgb555_rgba32 { public: void operator () (unsigned char* dst, const unsigned char* src, unsigned width) const { do { int rgb = *(int16*)src; dst[R] = (int8u)((rgb >> 7) & 0xF8); dst[G] = (int8u)((rgb >> 2) & 0xF8); dst[B] = (int8u)((rgb << 3) & 0xF8); dst[A] = (int8u)(rgb >> 15); src += 2; dst += 4; } while(--width); } }; //------------------------------------------------------------------------ typedef color_conv_rgb555_rgba32<1,2,3,0> color_conv_rgb555_to_argb32; //----color_conv_rgb555_to_argb32 typedef color_conv_rgb555_rgba32<3,2,1,0> color_conv_rgb555_to_abgr32; //----color_conv_rgb555_to_abgr32 typedef color_conv_rgb555_rgba32<2,1,0,3> color_conv_rgb555_to_bgra32; //----color_conv_rgb555_to_bgra32 typedef color_conv_rgb555_rgba32<0,1,2,3> color_conv_rgb555_to_rgba32; //----color_conv_rgb555_to_rgba32 //------------------------------------------------color_conv_rgba32_rgb555 template class color_conv_rgba32_rgb555 { public: void operator () (unsigned char* dst, const unsigned char* src, unsigned width) const { do { *(int16u*)dst = (int16u)(((unsigned(src[R]) << 7) & 0x7C00) | ((unsigned(src[G]) << 2) & 0x3E0) | ((unsigned(src[B]) >> 3)) | ((unsigned(src[A]) << 8) & 0x8000)); src += 4; dst += 2; } while(--width); } }; //------------------------------------------------------------------------ typedef color_conv_rgba32_rgb555<1,2,3,0> color_conv_argb32_to_rgb555; //----color_conv_argb32_to_rgb555 typedef color_conv_rgba32_rgb555<3,2,1,0> color_conv_abgr32_to_rgb555; //----color_conv_abgr32_to_rgb555 typedef color_conv_rgba32_rgb555<2,1,0,3> color_conv_bgra32_to_rgb555; //----color_conv_bgra32_to_rgb555 typedef color_conv_rgba32_rgb555<0,1,2,3> color_conv_rgba32_to_rgb555; //----color_conv_rgba32_to_rgb555 //------------------------------------------------color_conv_rgb565_rgba32 template class color_conv_rgb565_rgba32 { public: void operator () (unsigned char* dst, const unsigned char* src, unsigned width) const { do { int rgb = *(int16*)src; dst[R] = (rgb >> 8) & 0xF8; dst[G] = (rgb >> 3) & 0xFC; dst[B] = (rgb << 3) & 0xF8; dst[A] = 255; src += 2; dst += 4; } while(--width); } }; //------------------------------------------------------------------------ typedef color_conv_rgb565_rgba32<1,2,3,0> color_conv_rgb565_to_argb32; //----color_conv_rgb565_to_argb32 typedef color_conv_rgb565_rgba32<3,2,1,0> color_conv_rgb565_to_abgr32; //----color_conv_rgb565_to_abgr32 typedef color_conv_rgb565_rgba32<2,1,0,3> color_conv_rgb565_to_bgra32; //----color_conv_rgb565_to_bgra32 typedef color_conv_rgb565_rgba32<0,1,2,3> color_conv_rgb565_to_rgba32; //----color_conv_rgb565_to_rgba32 //------------------------------------------------color_conv_rgba32_rgb565 template class color_conv_rgba32_rgb565 { public: void operator () (unsigned char* dst, const unsigned char* src, unsigned width) const { do { *(int16u*)dst = (int16u)(((unsigned(src[R]) << 8) & 0xF800) | ((unsigned(src[G]) << 3) & 0x7E0) | ((unsigned(src[B]) >> 3))); src += 4; dst += 2; } while(--width); } }; //------------------------------------------------------------------------ typedef color_conv_rgba32_rgb565<1,2,3> color_conv_argb32_to_rgb565; //----color_conv_argb32_to_rgb565 typedef color_conv_rgba32_rgb565<3,2,1> color_conv_abgr32_to_rgb565; //----color_conv_abgr32_to_rgb565 typedef color_conv_rgba32_rgb565<2,1,0> color_conv_bgra32_to_rgb565; //----color_conv_bgra32_to_rgb565 typedef color_conv_rgba32_rgb565<0,1,2> color_conv_rgba32_to_rgb565; //----color_conv_rgba32_to_rgb565 //---------------------------------------------color_conv_rgb555_to_rgb565 class color_conv_rgb555_to_rgb565 { public: void operator () (unsigned char* dst, const unsigned char* src, unsigned width) const { do { unsigned rgb = *(int16u*)src; *(int16u*)dst = (int16u)(((rgb << 1) & 0xFFC0) | (rgb & 0x1F)); src += 2; dst += 2; } while(--width); } }; //----------------------------------------------color_conv_rgb565_to_rgb555 class color_conv_rgb565_to_rgb555 { public: void operator () (unsigned char* dst, const unsigned char* src, unsigned width) const { do { unsigned rgb = *(int16u*)src; *(int16u*)dst = (int16u)(((rgb >> 1) & 0x7FE0) | (rgb & 0x1F)); src += 2; dst += 2; } while(--width); } }; //------------------------------------------------------------------------ typedef color_conv_same<2> color_conv_rgb555_to_rgb555; //----color_conv_rgb555_to_rgb555 typedef color_conv_same<2> color_conv_rgb565_to_rgb565; //----color_conv_rgb565_to_rgb565 } #endif aggdraw-1.3.14/agg2/src/000077500000000000000000000000001417726601400146335ustar00rootroot00000000000000aggdraw-1.3.14/agg2/src/agg_arc.cpp000066400000000000000000000060231417726601400167230ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Arc vertex generator // //---------------------------------------------------------------------------- #include #include "agg_arc.h" namespace agg { //------------------------------------------------------------------------ arc::arc(double x, double y, double rx, double ry, double a1, double a2, bool ccw) : m_x(x), m_y(y), m_rx(rx), m_ry(ry), m_scale(1.0) { normalize(a1, a2, ccw); } //------------------------------------------------------------------------ void arc::init(double x, double y, double rx, double ry, double a1, double a2, bool ccw) { m_x = x; m_y = y; m_rx = rx; m_ry = ry; normalize(a1, a2, ccw); } //------------------------------------------------------------------------ void arc::approximation_scale(double s) { m_scale = s; if(m_initialized) { normalize(m_start, m_end, m_ccw); } } //------------------------------------------------------------------------ void arc::rewind(unsigned) { m_path_cmd = path_cmd_move_to; m_angle = m_start; } //------------------------------------------------------------------------ unsigned arc::vertex(double* x, double* y) { if(is_stop(m_path_cmd)) return path_cmd_stop; if((m_angle < m_end) != m_ccw) { *x = m_x + cos(m_end) * m_rx; *y = m_y + sin(m_end) * m_ry; m_path_cmd = path_cmd_stop; return path_cmd_line_to; } *x = m_x + cos(m_angle) * m_rx; *y = m_y + sin(m_angle) * m_ry; m_angle += m_da; unsigned pf = m_path_cmd; m_path_cmd = path_cmd_line_to; return pf; } //------------------------------------------------------------------------ void arc::normalize(double a1, double a2, bool ccw) { m_da = fabs(1.0 / ((m_rx + m_ry) * 0.5 * m_scale)); if(ccw) { while(a2 < a1) a2 += pi * 2.0; } else { while(a1 < a2) a1 += pi * 2.0; m_da = -m_da; } m_ccw = ccw; m_start = a1; m_end = a2; m_initialized = true; } } aggdraw-1.3.14/agg2/src/agg_arrowhead.cpp000066400000000000000000000070561417726601400201410ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Simple arrowhead/arrowtail generator // //---------------------------------------------------------------------------- #include "agg_arrowhead.h" namespace agg { //------------------------------------------------------------------------ arrowhead::arrowhead() : m_head_d1(1.0), m_head_d2(1.0), m_head_d3(1.0), m_head_d4(0.0), m_tail_d1(1.0), m_tail_d2(1.0), m_tail_d3(1.0), m_tail_d4(0.0), m_head_flag(false), m_tail_flag(false), m_curr_id(0), m_curr_coord(0) { } //------------------------------------------------------------------------ void arrowhead::rewind(unsigned id) { m_curr_id = id; m_curr_coord = 0; if(id == 0) { if(!m_tail_flag) { m_cmd[0] = path_cmd_stop; return; } m_coord[0] = m_tail_d1; m_coord[1] = 0.0; m_coord[2] = m_tail_d1 - m_tail_d4; m_coord[3] = m_tail_d3; m_coord[4] = -m_tail_d2 - m_tail_d4; m_coord[5] = m_tail_d3; m_coord[6] = -m_tail_d2; m_coord[7] = 0.0; m_coord[8] = -m_tail_d2 - m_tail_d4; m_coord[9] = -m_tail_d3; m_coord[10] = m_tail_d1 - m_tail_d4; m_coord[11] = -m_tail_d3; m_cmd[0] = path_cmd_move_to; m_cmd[1] = path_cmd_line_to; m_cmd[2] = path_cmd_line_to; m_cmd[3] = path_cmd_line_to; m_cmd[4] = path_cmd_line_to; m_cmd[5] = path_cmd_line_to; m_cmd[7] = path_cmd_end_poly | path_flags_close | path_flags_ccw; m_cmd[6] = path_cmd_stop; return; } if(id == 1) { if(!m_head_flag) { m_cmd[0] = path_cmd_stop; return; } m_coord[0] = -m_head_d1; m_coord[1] = 0.0; m_coord[2] = m_head_d2 + m_head_d4; m_coord[3] = -m_head_d3; m_coord[4] = m_head_d2; m_coord[5] = 0.0; m_coord[6] = m_head_d2 + m_head_d4; m_coord[7] = m_head_d3; m_cmd[0] = path_cmd_move_to; m_cmd[1] = path_cmd_line_to; m_cmd[2] = path_cmd_line_to; m_cmd[3] = path_cmd_line_to; m_cmd[4] = path_cmd_end_poly | path_flags_close | path_flags_ccw; m_cmd[5] = path_cmd_stop; return; } } //------------------------------------------------------------------------ unsigned arrowhead::vertex(double* x, double* y) { if(m_curr_id < 2) { unsigned curr_idx = m_curr_coord * 2; *x = m_coord[curr_idx]; *y = m_coord[curr_idx + 1]; return m_cmd[m_curr_coord++]; } return path_cmd_stop; } } aggdraw-1.3.14/agg2/src/agg_bezier_arc.cpp000066400000000000000000000170331417726601400202660ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Arc generator. Produces at most 4 consecutive cubic bezier curves, i.e., // 4, 7, 10, or 13 vertices. // //---------------------------------------------------------------------------- #include #include "agg_bezier_arc.h" namespace agg { //------------------------------------------------------------arc_to_bezier void arc_to_bezier(double cx, double cy, double rx, double ry, double start_angle, double sweep_angle, double* curve) { double x0 = cos(sweep_angle / 2.0); double y0 = sin(sweep_angle / 2.0); double tx = (1.0 - x0) * 4.0 / 3.0; double ty = y0 - tx * x0 / y0; double px[4]; double py[4]; px[0] = x0; py[0] = -y0; px[1] = x0 + tx; py[1] = -ty; px[2] = x0 + tx; py[2] = ty; px[3] = x0; py[3] = y0; double sn = sin(start_angle + sweep_angle / 2.0); double cs = cos(start_angle + sweep_angle / 2.0); unsigned i; for(i = 0; i < 4; i++) { curve[i * 2] = cx + rx * (px[i] * cs - py[i] * sn); curve[i * 2 + 1] = cy + ry * (px[i] * sn + py[i] * cs); } } //------------------------------------------------------------------------ void bezier_arc::init(double x, double y, double rx, double ry, double start_angle, double sweep_angle) { start_angle = fmod(start_angle, 2.0 * pi); if(sweep_angle >= 2.0 * pi) sweep_angle = 2.0 * pi; if(sweep_angle <= -2.0 * pi) sweep_angle = -2.0 * pi; double total_sweep = 0.0; double local_sweep = 0.0; m_num_vertices = 2; bool done = false; do { if(sweep_angle < 0.0) { local_sweep = -pi * 0.5; total_sweep -= pi * 0.5; if(total_sweep <= sweep_angle) { local_sweep = sweep_angle - (total_sweep + pi * 0.5); done = true; } } else { local_sweep = pi * 0.5; total_sweep += pi * 0.5; if(total_sweep >= sweep_angle) { local_sweep = sweep_angle - (total_sweep - pi * 0.5); done = true; } } arc_to_bezier(x, y, rx, ry, start_angle, local_sweep, m_vertices + m_num_vertices - 2); m_num_vertices += 6; start_angle += local_sweep; } while(!done && m_num_vertices < 26); } //-------------------------------------------------------------------- void bezier_arc_svg::init(double x0, double y0, double rx, double ry, double angle, bool large_arc_flag, bool sweep_flag, double x2, double y2) { m_radii_ok = true; if(rx < 0.0) rx = -rx; if(ry < 0.0) ry = -rx; // Calculate the middle point between // the current and the final points //------------------------ double dx2 = (x0 - x2) / 2.0; double dy2 = (y0 - y2) / 2.0; // Convert angle from degrees to radians //------------------------ double cos_a = cos(angle); double sin_a = sin(angle); // Calculate (x1, y1) //------------------------ double x1 = cos_a * dx2 + sin_a * dy2; double y1 = -sin_a * dx2 + cos_a * dy2; // Ensure radii are large enough //------------------------ double prx = rx * rx; double pry = ry * ry; double px1 = x1 * x1; double py1 = y1 * y1; // Check that radii are large enough //------------------------ double radii_check = px1/prx + py1/pry; if(radii_check > 1.0) { rx = sqrt(radii_check) * rx; ry = sqrt(radii_check) * ry; prx = rx * rx; pry = ry * ry; if(radii_check > 10.0) m_radii_ok = false; } // Calculate (cx1, cy1) //------------------------ double sign = (large_arc_flag == sweep_flag) ? -1.0 : 1.0; double sq = (prx*pry - prx*py1 - pry*px1) / (prx*py1 + pry*px1); double coef = sign * sqrt((sq < 0) ? 0 : sq); double cx1 = coef * ((rx * y1) / ry); double cy1 = coef * -((ry * x1) / rx); // // Calculate (cx, cy) from (cx1, cy1) //------------------------ double sx2 = (x0 + x2) / 2.0; double sy2 = (y0 + y2) / 2.0; double cx = sx2 + (cos_a * cx1 - sin_a * cy1); double cy = sy2 + (sin_a * cx1 + cos_a * cy1); // Calculate the start_angle (angle1) and the sweep_angle (dangle) //------------------------ double ux = (x1 - cx1) / rx; double uy = (y1 - cy1) / ry; double vx = (-x1 - cx1) / rx; double vy = (-y1 - cy1) / ry; double p, n; // Calculate the angle start //------------------------ n = sqrt(ux*ux + uy*uy); p = ux; // (1 * ux) + (0 * uy) sign = (uy < 0) ? -1.0 : 1.0; double v = p / n; if(v < -1.0) v = -1.0; if(v > 1.0) v = 1.0; double start_angle = sign * acos(v); // Calculate the sweep angle //------------------------ n = sqrt((ux*ux + uy*uy) * (vx*vx + vy*vy)); p = ux * vx + uy * vy; sign = (ux * vy - uy * vx < 0) ? -1.0 : 1.0; v = p / n; if(v < -1.0) v = -1.0; if(v > 1.0) v = 1.0; double sweep_angle = sign * acos(v); if(!sweep_flag && sweep_angle > 0) { sweep_angle -= pi * 2.0; } else if (sweep_flag && sweep_angle < 0) { sweep_angle += pi * 2.0; } // We can now build and transform the resulting arc //------------------------ m_arc.init(0.0, 0.0, rx, ry, start_angle, sweep_angle); trans_affine mtx = trans_affine_rotation(angle); mtx *= trans_affine_translation(cx, cy); for(unsigned i = 2; i < m_arc.num_vertices()-2; i += 2) { mtx.transform(m_arc.vertices() + i, m_arc.vertices() + i + 1); } // We must make sure that the starting and ending points // exactly coincide with the initial (x0,y0) and (x2,y2) m_arc.vertices()[0] = x0; m_arc.vertices()[1] = y0; if(m_arc.num_vertices() > 2) { m_arc.vertices()[m_arc.num_vertices() - 2] = x2; m_arc.vertices()[m_arc.num_vertices() - 1] = y2; } } } aggdraw-1.3.14/agg2/src/agg_bspline.cpp000066400000000000000000000177121417726601400176210ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // class bspline // //---------------------------------------------------------------------------- #include "agg_bspline.h" namespace agg { //------------------------------------------------------------------------ bspline::~bspline() { delete [] m_am; } //------------------------------------------------------------------------ bspline::bspline() : m_max(0), m_num(0), m_x(0), m_y(0), m_am(0), m_last_idx(-1) { } //------------------------------------------------------------------------ bspline::bspline(int num) : m_max(0), m_num(0), m_x(0), m_y(0), m_am(0), m_last_idx(-1) { init(num); } //------------------------------------------------------------------------ bspline::bspline(int num, const double* x, const double* y) : m_max(0), m_num(0), m_x(0), m_y(0), m_am(0), m_last_idx(-1) { init(num, x, y); } //------------------------------------------------------------------------ void bspline::init(int max) { if(max > 2 && max > m_max) { delete [] m_am; m_am = new double[max * 3]; m_max = max; m_x = m_am + m_max; m_y = m_am + m_max * 2; } m_num = 0; m_last_idx = -1; } //------------------------------------------------------------------------ void bspline::add_point(double x, double y) { if(m_num < m_max) { m_x[m_num] = x; m_y[m_num] = y; ++m_num; } } //------------------------------------------------------------------------ void bspline::prepare() { if(m_num > 2) { int i, k, n1; double* temp; double* r; double* s; double* al; double h, p, d, f, e; for(k = 0; k < m_num; k++) { m_am[k] = 0.0; } n1 = 3 * m_num; al = new double[n1]; temp = al; for(k = 0; k < n1; k++) { temp[k] = 0.0; } r = temp + m_num; s = temp + m_num * 2; n1 = m_num - 1; d = m_x[1] - m_x[0]; e = (m_y[1] - m_y[0]) / d; for(k = 1; k < n1; k++) { h = d; d = m_x[k + 1] - m_x[k]; f = e; e = (m_y[k + 1] - m_y[k]) / d; al[k] = d / (d + h); r[k] = 1.0 - al[k]; s[k] = 6.0 * (e - f) / (h + d); } for(k = 1; k < n1; k++) { p = 1.0 / (r[k] * al[k - 1] + 2.0); al[k] *= -p; s[k] = (s[k] - r[k] * s[k - 1]) * p; } m_am[n1] = 0.0; al[n1 - 1] = s[n1 - 1]; m_am[n1 - 1] = al[n1 - 1]; for(k = n1 - 2, i = 0; i < m_num - 2; i++, k--) { al[k] = al[k] * al[k + 1] + s[k]; m_am[k] = al[k]; } delete al; } m_last_idx = -1; } //------------------------------------------------------------------------ void bspline::init(int num, const double* x, const double* y) { if(num > 2) { init(num); int i; for(i = 0; i < num; i++) { add_point(*x++, *y++); } prepare(); } m_last_idx = -1; } //------------------------------------------------------------------------ void bspline::bsearch(int n, const double *x, double x0, int *i) { int j = n - 1; int k; for(*i = 0; (j - *i) > 1; ) { if(x0 < x[k = (*i + j) >> 1]) j = k; else *i = k; } } //------------------------------------------------------------------------ double bspline::interpolation(double x, int i) const { int j = i + 1; double d = m_x[i] - m_x[j]; double h = x - m_x[j]; double r = m_x[i] - x; double p = d * d / 6.0; return (m_am[j] * r * r * r + m_am[i] * h * h * h) / 6.0 / d + ((m_y[j] - m_am[j] * p) * r + (m_y[i] - m_am[i] * p) * h) / d; } //------------------------------------------------------------------------ double bspline::extrapolation_left(double x) const { double d = m_x[1] - m_x[0]; return (-d * m_am[1] / 6 + (m_y[1] - m_y[0]) / d) * (x - m_x[0]) + m_y[0]; } //------------------------------------------------------------------------ double bspline::extrapolation_right(double x) const { double d = m_x[m_num - 1] - m_x[m_num - 2]; return (d * m_am[m_num - 2] / 6 + (m_y[m_num - 1] - m_y[m_num - 2]) / d) * (x - m_x[m_num - 1]) + m_y[m_num - 1]; } //------------------------------------------------------------------------ double bspline::get(double x) const { if(m_num > 2) { int i; // Extrapolation on the left if(x < m_x[0]) return extrapolation_left(x); // Extrapolation on the right if(x >= m_x[m_num - 1]) return extrapolation_right(x); // Interpolation bsearch(m_num, m_x, x, &i); return interpolation(x, i); } return 0.0; } //------------------------------------------------------------------------ double bspline::get_stateful(double x) const { if(m_num > 2) { // Extrapolation on the left if(x < m_x[0]) return extrapolation_left(x); // Extrapolation on the right if(x >= m_x[m_num - 1]) return extrapolation_right(x); if(m_last_idx >= 0) { // Check if x is not in current range if(x < m_x[m_last_idx] || x > m_x[m_last_idx + 1]) { // Check if x between next points (most probably) if(m_last_idx < m_num - 2 && x >= m_x[m_last_idx + 1] && x <= m_x[m_last_idx + 2]) { ++m_last_idx; } else if(m_last_idx > 0 && x >= m_x[m_last_idx - 1] && x <= m_x[m_last_idx]) { // x is between pevious points --m_last_idx; } else { // Else perform full search bsearch(m_num, m_x, x, &m_last_idx); } } return interpolation(x, m_last_idx); } else { // Interpolation bsearch(m_num, m_x, x, &m_last_idx); return interpolation(x, m_last_idx); } } return 0.0; } } aggdraw-1.3.14/agg2/src/agg_curves.cpp000066400000000000000000000141621417726601400174700ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // classes curve3 and curve4 // //---------------------------------------------------------------------------- #include #include "agg_curves.h" namespace agg { //------------------------------------------------------------------------ void curve3::init(double x1, double y1, double x2, double y2, double x3, double y3) { m_start_x = x1; m_start_y = y1; m_end_x = x3; m_end_y = y3; double dx1 = x2 - x1; double dy1 = y2 - y1; double dx2 = x3 - x2; double dy2 = y3 - y2; double len = sqrt(dx1 * dx1 + dy1 * dy1) + sqrt(dx2 * dx2 + dy2 * dy2); m_num_steps = int(len * 0.25 * m_scale); if(m_num_steps < 2) { m_num_steps = 2; } double subdivide_step = 1.0 / m_num_steps; double subdivide_step2 = subdivide_step * subdivide_step; double tmpx = (x1 - x2 * 2.0 + x3) * subdivide_step2; double tmpy = (y1 - y2 * 2.0 + y3) * subdivide_step2; m_saved_fx = m_fx = x1; m_saved_fy = m_fy = y1; m_saved_dfx = m_dfx = tmpx + (x2 - x1) * (2.0 * subdivide_step); m_saved_dfy = m_dfy = tmpy + (y2 - y1) * (2.0 * subdivide_step); m_ddfx = tmpx * 2.0; m_ddfy = tmpy * 2.0; m_step = m_num_steps; } //------------------------------------------------------------------------ void curve3::rewind(unsigned) { if(m_num_steps == 0) { m_step = -1; return; } m_step = m_num_steps; m_fx = m_saved_fx; m_fy = m_saved_fy; m_dfx = m_saved_dfx; m_dfy = m_saved_dfy; } //------------------------------------------------------------------------ unsigned curve3::vertex(double* x, double* y) { if(m_step < 0) return path_cmd_stop; if(m_step == m_num_steps) { *x = m_start_x; *y = m_start_y; --m_step; return path_cmd_move_to; } if(m_step == 0) { *x = m_end_x; *y = m_end_y; --m_step; return path_cmd_line_to; } m_fx += m_dfx; m_fy += m_dfy; m_dfx += m_ddfx; m_dfy += m_ddfy; *x = m_fx; *y = m_fy; --m_step; return path_cmd_line_to; } //------------------------------------------------------------------------ void curve4::init(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) { m_start_x = x1; m_start_y = y1; m_end_x = x4; m_end_y = y4; double dx1 = x2 - x1; double dy1 = y2 - y1; double dx2 = x3 - x2; double dy2 = y3 - y2; double dx3 = x4 - x3; double dy3 = y4 - y3; double len = sqrt(dx1 * dx1 + dy1 * dy1) + sqrt(dx2 * dx2 + dy2 * dy2) + sqrt(dx3 * dx3 + dy3 * dy3); m_num_steps = int(len * 0.25 * m_scale); if(m_num_steps < 2) { m_num_steps = 2; } double subdivide_step = 1.0 / m_num_steps; double subdivide_step2 = subdivide_step * subdivide_step; double subdivide_step3 = subdivide_step * subdivide_step * subdivide_step; double pre1 = 3.0 * subdivide_step; double pre2 = 3.0 * subdivide_step2; double pre4 = 6.0 * subdivide_step2; double pre5 = 6.0 * subdivide_step3; double tmp1x = x1 - x2 * 2.0 + x3; double tmp1y = y1 - y2 * 2.0 + y3; double tmp2x = (x2 - x3) * 3.0 - x1 + x4; double tmp2y = (y2 - y3) * 3.0 - y1 + y4; m_saved_fx = m_fx = x1; m_saved_fy = m_fy = y1; m_saved_dfx = m_dfx = (x2 - x1) * pre1 + tmp1x * pre2 + tmp2x * subdivide_step3; m_saved_dfy = m_dfy = (y2 - y1) * pre1 + tmp1y * pre2 + tmp2y * subdivide_step3; m_saved_ddfx = m_ddfx = tmp1x * pre4 + tmp2x * pre5; m_saved_ddfy = m_ddfy = tmp1y * pre4 + tmp2y * pre5; m_dddfx = tmp2x * pre5; m_dddfy = tmp2y * pre5; m_step = m_num_steps; } //------------------------------------------------------------------------ void curve4::rewind(unsigned) { if(m_num_steps == 0) { m_step = -1; return; } m_step = m_num_steps; m_fx = m_saved_fx; m_fy = m_saved_fy; m_dfx = m_saved_dfx; m_dfy = m_saved_dfy; m_ddfx = m_saved_ddfx; m_ddfy = m_saved_ddfy; } //------------------------------------------------------------------------ unsigned curve4::vertex(double* x, double* y) { if(m_step < 0) return path_cmd_stop; if(m_step == m_num_steps) { *x = m_start_x; *y = m_start_y; --m_step; return path_cmd_move_to; } if(m_step == 0) { *x = m_end_x; *y = m_end_y; --m_step; return path_cmd_line_to; } m_fx += m_dfx; m_fy += m_dfy; m_dfx += m_ddfx; m_dfy += m_ddfy; m_ddfx += m_dddfx; m_ddfy += m_dddfy; *x = m_fx; *y = m_fy; --m_step; return path_cmd_line_to; } } aggdraw-1.3.14/agg2/src/agg_embedded_raster_fonts.cpp000066400000000000000000014020201417726601400224760ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #include "agg_embedded_raster_fonts.h" namespace agg { const int8u gse4x6[] = { 6, 0, 32, 128-32, 0x00,0x00,0x07,0x00,0x0e,0x00,0x15,0x00,0x1c,0x00,0x23,0x00,0x2a,0x00,0x31,0x00,0x38,0x00, 0x3f,0x00,0x46,0x00,0x4d,0x00,0x54,0x00,0x5b,0x00,0x62,0x00,0x69,0x00,0x70,0x00,0x77,0x00, 0x7e,0x00,0x85,0x00,0x8c,0x00,0x93,0x00,0x9a,0x00,0xa1,0x00,0xa8,0x00,0xaf,0x00,0xb6,0x00, 0xbd,0x00,0xc4,0x00,0xcb,0x00,0xd2,0x00,0xd9,0x00,0xe0,0x00,0xe7,0x00,0xee,0x00,0xf5,0x00, 0xfc,0x00,0x03,0x01,0x0a,0x01,0x11,0x01,0x18,0x01,0x1f,0x01,0x26,0x01,0x2d,0x01,0x34,0x01, 0x3b,0x01,0x42,0x01,0x49,0x01,0x50,0x01,0x57,0x01,0x5e,0x01,0x65,0x01,0x6c,0x01,0x73,0x01, 0x7a,0x01,0x81,0x01,0x88,0x01,0x8f,0x01,0x96,0x01,0x9d,0x01,0xa4,0x01,0xab,0x01,0xb2,0x01, 0xb9,0x01,0xc0,0x01,0xc7,0x01,0xce,0x01,0xd5,0x01,0xdc,0x01,0xe3,0x01,0xea,0x01,0xf1,0x01, 0xf8,0x01,0xff,0x01,0x06,0x02,0x0d,0x02,0x14,0x02,0x1b,0x02,0x22,0x02,0x29,0x02,0x30,0x02, 0x37,0x02,0x3e,0x02,0x45,0x02,0x4c,0x02,0x53,0x02,0x5a,0x02,0x61,0x02,0x68,0x02,0x6f,0x02, 0x76,0x02,0x7d,0x02,0x84,0x02,0x8b,0x02,0x92,0x02,0x99,0x02, 4, // 0x20 ' ' 0x00,0x00,0x00,0x00,0x00,0x00, 4, // 0x21 '!' 0x40,0x40,0x40,0x00,0x40,0x00, 4, // 0x22 '"' 0xa0,0xa0,0x00,0x00,0x00,0x00, 4, // 0x23 '#' 0x60,0xf0,0x60,0xf0,0x60,0x00, 4, // 0x24 '$' 0x40,0x60,0xc0,0x60,0xc0,0x40, 4, // 0x25 '%' 0xa0,0x20,0x40,0x80,0xa0,0x00, 4, // 0x26 '&' 0xe0,0xa0,0x50,0xa0,0xd0,0x00, 4, // 0x27 ''' 0x40,0x40,0x00,0x00,0x00,0x00, 4, // 0x28 '(' 0x20,0x40,0x40,0x40,0x20,0x00, 4, // 0x29 ')' 0x40,0x20,0x20,0x20,0x40,0x00, 4, // 0x2a '*' 0xa0,0x40,0xe0,0x40,0xa0,0x00, 4, // 0x2b '+' 0x40,0x40,0xe0,0x40,0x40,0x00, 4, // 0x2c ',' 0x00,0x00,0x00,0x40,0x40,0x80, 4, // 0x2d '-' 0x00,0x00,0xe0,0x00,0x00,0x00, 4, // 0x2e '.' 0x00,0x00,0x00,0x00,0x40,0x00, 4, // 0x2f '/' 0x10,0x20,0x20,0x40,0x40,0x80, 4, // 0x30 '0' 0xe0,0xa0,0xa0,0xa0,0xe0,0x00, 4, // 0x31 '1' 0x40,0xc0,0x40,0x40,0xe0,0x00, 4, // 0x32 '2' 0xe0,0xa0,0x20,0x40,0xe0,0x00, 4, // 0x33 '3' 0xe0,0x20,0x40,0x20,0xe0,0x00, 4, // 0x34 '4' 0xa0,0xa0,0xe0,0x20,0x20,0x00, 4, // 0x35 '5' 0xe0,0x80,0xc0,0x20,0xc0,0x00, 4, // 0x36 '6' 0x40,0x80,0xe0,0xa0,0xe0,0x00, 4, // 0x37 '7' 0xe0,0xa0,0x20,0x40,0x40,0x00, 4, // 0x38 '8' 0xe0,0xa0,0x40,0xa0,0xe0,0x00, 4, // 0x39 '9' 0xe0,0xa0,0xe0,0x20,0xc0,0x00, 4, // 0x3a ':' 0x00,0x40,0x00,0x40,0x00,0x00, 4, // 0x3b ';' 0x00,0x40,0x00,0x40,0x40,0x80, 4, // 0x3c '<' 0x20,0x40,0x80,0x40,0x20,0x00, 4, // 0x3d '=' 0x00,0xe0,0x00,0xe0,0x00,0x00, 4, // 0x3e '>' 0x80,0x40,0x20,0x40,0x80,0x00, 4, // 0x3f '?' 0xc0,0x20,0x40,0x00,0x40,0x00, 4, // 0x40 '@' 0x40,0xa0,0xe0,0xe0,0x80,0x60, 4, // 0x41 'A' 0x40,0xa0,0xe0,0xa0,0xa0,0x00, 4, // 0x42 'B' 0xc0,0xa0,0xc0,0xa0,0xc0,0x00, 4, // 0x43 'C' 0x60,0x80,0x80,0x80,0x60,0x00, 4, // 0x44 'D' 0xc0,0xa0,0xa0,0xa0,0xc0,0x00, 4, // 0x45 'E' 0xe0,0x80,0xc0,0x80,0xe0,0x00, 4, // 0x46 'F' 0xe0,0x80,0xc0,0x80,0x80,0x00, 4, // 0x47 'G' 0x60,0x80,0xa0,0xa0,0x40,0x00, 4, // 0x48 'H' 0xa0,0xa0,0xe0,0xa0,0xa0,0x00, 4, // 0x49 'I' 0xe0,0x40,0x40,0x40,0xe0,0x00, 4, // 0x4a 'J' 0x20,0x20,0x20,0x20,0xa0,0x40, 4, // 0x4b 'K' 0xa0,0xa0,0xc0,0xc0,0xa0,0x00, 4, // 0x4c 'L' 0x80,0x80,0x80,0x80,0xe0,0x00, 4, // 0x4d 'M' 0xa0,0xe0,0xa0,0xa0,0xa0,0x00, 4, // 0x4e 'N' 0x90,0xd0,0xb0,0x90,0x90,0x00, 4, // 0x4f 'O' 0x40,0xa0,0xa0,0xa0,0x40,0x00, 4, // 0x50 'P' 0xc0,0xa0,0xa0,0xc0,0x80,0x00, 4, // 0x51 'Q' 0x40,0xa0,0xa0,0xa0,0x60,0x00, 4, // 0x52 'R' 0xc0,0xa0,0xa0,0xc0,0xa0,0x00, 4, // 0x53 'S' 0x60,0x80,0x40,0x20,0xc0,0x00, 4, // 0x54 'T' 0xe0,0x40,0x40,0x40,0x40,0x00, 4, // 0x55 'U' 0xa0,0xa0,0xa0,0xa0,0xe0,0x00, 4, // 0x56 'V' 0xa0,0xa0,0xa0,0xa0,0x40,0x00, 4, // 0x57 'W' 0xa0,0xa0,0xa0,0xe0,0xa0,0x00, 4, // 0x58 'X' 0xa0,0xa0,0x40,0xa0,0xa0,0x00, 4, // 0x59 'Y' 0xa0,0xa0,0x40,0x40,0x40,0x00, 4, // 0x5a 'Z' 0xe0,0x20,0x40,0x80,0xe0,0x00, 4, // 0x5b '[' 0xc0,0x80,0x80,0x80,0xc0,0x00, 4, // 0x5c '\' 0x80,0x40,0x40,0x20,0x20,0x10, 4, // 0x5d ']' 0xc0,0x40,0x40,0x40,0xc0,0x00, 4, // 0x5e '^' 0x40,0xa0,0x00,0x00,0x00,0x00, 4, // 0x5f '_' 0x00,0x00,0x00,0x00,0x00,0xf0, 4, // 0x60 '`' 0x40,0x20,0x00,0x00,0x00,0x00, 4, // 0x61 'a' 0x00,0x60,0xa0,0xa0,0x70,0x00, 4, // 0x62 'b' 0x80,0x80,0xc0,0xa0,0xc0,0x00, 4, // 0x63 'c' 0x00,0x60,0x80,0x80,0x60,0x00, 4, // 0x64 'd' 0x20,0x20,0x60,0xa0,0x60,0x00, 4, // 0x65 'e' 0x00,0x40,0xe0,0x80,0x60,0x00, 4, // 0x66 'f' 0x20,0x40,0xe0,0x40,0x40,0x00, 4, // 0x67 'g' 0x00,0x60,0xa0,0x60,0x20,0xc0, 4, // 0x68 'h' 0x80,0x80,0xc0,0xa0,0xa0,0x00, 4, // 0x69 'i' 0x40,0x00,0xc0,0x40,0xe0,0x00, 4, // 0x6a 'j' 0x40,0x00,0xc0,0x40,0x40,0x80, 4, // 0x6b 'k' 0x80,0x80,0xa0,0xc0,0xa0,0x00, 4, // 0x6c 'l' 0xc0,0x40,0x40,0x40,0xe0,0x00, 4, // 0x6d 'm' 0x00,0xa0,0xf0,0xf0,0x90,0x00, 4, // 0x6e 'n' 0x00,0xc0,0xa0,0xa0,0xa0,0x00, 4, // 0x6f 'o' 0x00,0x40,0xa0,0xa0,0x40,0x00, 4, // 0x70 'p' 0x00,0xc0,0xa0,0xc0,0x80,0x80, 4, // 0x71 'q' 0x00,0x60,0xa0,0x60,0x20,0x20, 4, // 0x72 'r' 0x00,0xa0,0x50,0x40,0x40,0x00, 4, // 0x73 's' 0x00,0x60,0xc0,0x20,0xc0,0x00, 4, // 0x74 't' 0x40,0x40,0xe0,0x40,0x60,0x00, 4, // 0x75 'u' 0x00,0xa0,0xa0,0xa0,0x60,0x00, 4, // 0x76 'v' 0x00,0xa0,0xa0,0xa0,0x40,0x00, 4, // 0x77 'w' 0x00,0xa0,0xa0,0xe0,0xa0,0x00, 4, // 0x78 'x' 0x00,0xa0,0x40,0xa0,0xa0,0x00, 4, // 0x79 'y' 0x00,0xa0,0xa0,0x60,0x20,0xc0, 4, // 0x7a 'z' 0x00,0xe0,0x40,0x80,0xe0,0x00, 4, // 0x7b '{' 0x30,0x20,0xc0,0x20,0x30,0x00, 4, // 0x7c '|' 0x40,0x40,0x00,0x40,0x40,0x40, 4, // 0x7d '}' 0xc0,0x40,0x30,0x40,0xc0,0x00, 4, // 0x7e '~' 0x50,0xa0,0x00,0x00,0x00,0x00, 4, // 0x7f '' 0x00,0x60,0x90,0xf0,0x00,0x00, 0 }; const int8u gse4x8[] = { 8, 0, 32, 128-32, 0x00,0x00,0x09,0x00,0x12,0x00,0x1b,0x00,0x24,0x00,0x2d,0x00,0x36,0x00,0x3f,0x00,0x48,0x00, 0x51,0x00,0x5a,0x00,0x63,0x00,0x6c,0x00,0x75,0x00,0x7e,0x00,0x87,0x00,0x90,0x00,0x99,0x00, 0xa2,0x00,0xab,0x00,0xb4,0x00,0xbd,0x00,0xc6,0x00,0xcf,0x00,0xd8,0x00,0xe1,0x00,0xea,0x00, 0xf3,0x00,0xfc,0x00,0x05,0x01,0x0e,0x01,0x17,0x01,0x20,0x01,0x29,0x01,0x32,0x01,0x3b,0x01, 0x44,0x01,0x4d,0x01,0x56,0x01,0x5f,0x01,0x68,0x01,0x71,0x01,0x7a,0x01,0x83,0x01,0x8c,0x01, 0x95,0x01,0x9e,0x01,0xa7,0x01,0xb0,0x01,0xb9,0x01,0xc2,0x01,0xcb,0x01,0xd4,0x01,0xdd,0x01, 0xe6,0x01,0xef,0x01,0xf8,0x01,0x01,0x02,0x0a,0x02,0x13,0x02,0x1c,0x02,0x25,0x02,0x2e,0x02, 0x37,0x02,0x40,0x02,0x49,0x02,0x52,0x02,0x5b,0x02,0x64,0x02,0x6d,0x02,0x76,0x02,0x7f,0x02, 0x88,0x02,0x91,0x02,0x9a,0x02,0xa3,0x02,0xac,0x02,0xb5,0x02,0xbe,0x02,0xc7,0x02,0xd0,0x02, 0xd9,0x02,0xe2,0x02,0xeb,0x02,0xf4,0x02,0xfd,0x02,0x06,0x03,0x0f,0x03,0x18,0x03,0x21,0x03, 0x2a,0x03,0x33,0x03,0x3c,0x03,0x45,0x03,0x4e,0x03,0x57,0x03, 4, // 0x20 ' ' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 4, // 0x21 '!' 0x00,0x40,0x40,0x40,0x40,0x00,0x40,0x00, 4, // 0x22 '"' 0x00,0xa0,0xa0,0x00,0x00,0x00,0x00,0x00, 4, // 0x23 '#' 0x60,0x60,0xf0,0x60,0x60,0xf0,0x60,0x60, 4, // 0x24 '$' 0x40,0x60,0xc0,0xc0,0x60,0x60,0xc0,0x40, 4, // 0x25 '%' 0x00,0xa0,0x20,0x40,0x40,0x80,0xa0,0x00, 4, // 0x26 '&' 0x00,0x40,0xa0,0xa0,0x40,0xb0,0xa0,0x70, 4, // 0x27 ''' 0x00,0x40,0x40,0x00,0x00,0x00,0x00,0x00, 4, // 0x28 '(' 0x20,0x40,0x80,0x80,0x80,0x80,0x40,0x20, 4, // 0x29 ')' 0x80,0x40,0x20,0x20,0x20,0x20,0x40,0x80, 4, // 0x2a '*' 0x00,0xa0,0x40,0xe0,0x40,0xa0,0x00,0x00, 4, // 0x2b '+' 0x00,0x40,0x40,0xe0,0x40,0x40,0x00,0x00, 4, // 0x2c ',' 0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x80, 4, // 0x2d '-' 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, 4, // 0x2e '.' 0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00, 4, // 0x2f '/' 0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x80, 4, // 0x30 '0' 0x00,0xe0,0xa0,0xa0,0xa0,0xa0,0xe0,0x00, 4, // 0x31 '1' 0x00,0x40,0xc0,0x40,0x40,0x40,0xe0,0x00, 4, // 0x32 '2' 0x00,0xe0,0xa0,0x20,0x40,0x80,0xe0,0x00, 4, // 0x33 '3' 0x00,0xe0,0x20,0x40,0x20,0x20,0xe0,0x00, 4, // 0x34 '4' 0x00,0x60,0xa0,0xa0,0xf0,0x20,0x20,0x00, 4, // 0x35 '5' 0x00,0xe0,0x80,0xc0,0x20,0x20,0xc0,0x00, 4, // 0x36 '6' 0x00,0x40,0x80,0xe0,0xa0,0xa0,0xe0,0x00, 4, // 0x37 '7' 0x00,0xe0,0xa0,0x20,0x40,0x40,0x40,0x00, 4, // 0x38 '8' 0x00,0xe0,0xa0,0x40,0xa0,0xa0,0xe0,0x00, 4, // 0x39 '9' 0x00,0xe0,0xa0,0xe0,0x20,0x20,0x40,0x00, 4, // 0x3a ':' 0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00, 4, // 0x3b ';' 0x00,0x00,0x40,0x00,0x00,0x40,0x40,0x80, 4, // 0x3c '<' 0x00,0x20,0x40,0x80,0x40,0x20,0x00,0x00, 4, // 0x3d '=' 0x00,0x00,0xe0,0x00,0xe0,0x00,0x00,0x00, 4, // 0x3e '>' 0x00,0x80,0x40,0x20,0x40,0x80,0x00,0x00, 4, // 0x3f '?' 0x00,0x40,0xa0,0x20,0x40,0x00,0x40,0x00, 4, // 0x40 '@' 0x00,0x40,0xa0,0xe0,0xe0,0x80,0x60,0x00, 4, // 0x41 'A' 0x00,0x40,0xa0,0xa0,0xe0,0xa0,0xa0,0x00, 4, // 0x42 'B' 0x00,0xc0,0xa0,0xc0,0xa0,0xa0,0xc0,0x00, 4, // 0x43 'C' 0x00,0x40,0xa0,0x80,0x80,0xa0,0x40,0x00, 4, // 0x44 'D' 0x00,0xc0,0xa0,0xa0,0xa0,0xa0,0xc0,0x00, 4, // 0x45 'E' 0x00,0xe0,0x80,0xc0,0x80,0x80,0xe0,0x00, 4, // 0x46 'F' 0x00,0xe0,0x80,0xc0,0x80,0x80,0x80,0x00, 4, // 0x47 'G' 0x00,0x60,0x80,0xa0,0xa0,0xa0,0x40,0x00, 4, // 0x48 'H' 0x00,0xa0,0xa0,0xe0,0xa0,0xa0,0xa0,0x00, 4, // 0x49 'I' 0x00,0xe0,0x40,0x40,0x40,0x40,0xe0,0x00, 4, // 0x4a 'J' 0x00,0x20,0x20,0x20,0x20,0xa0,0x40,0x00, 4, // 0x4b 'K' 0x00,0xa0,0xa0,0xc0,0xc0,0xa0,0xa0,0x00, 4, // 0x4c 'L' 0x00,0x80,0x80,0x80,0x80,0x80,0xe0,0x00, 4, // 0x4d 'M' 0x00,0xa0,0xe0,0xa0,0xa0,0xa0,0xa0,0x00, 4, // 0x4e 'N' 0x00,0x90,0x90,0xd0,0xb0,0x90,0x90,0x00, 4, // 0x4f 'O' 0x00,0x40,0xa0,0xa0,0xa0,0xa0,0x40,0x00, 4, // 0x50 'P' 0x00,0xc0,0xa0,0xa0,0xc0,0x80,0x80,0x00, 4, // 0x51 'Q' 0x00,0x40,0xa0,0xa0,0xa0,0xa0,0x60,0x00, 4, // 0x52 'R' 0x00,0xc0,0xa0,0xa0,0xc0,0xc0,0xa0,0x00, 4, // 0x53 'S' 0x00,0x60,0x80,0x40,0x20,0x20,0xc0,0x00, 4, // 0x54 'T' 0x00,0xe0,0x40,0x40,0x40,0x40,0x40,0x00, 4, // 0x55 'U' 0x00,0xa0,0xa0,0xa0,0xa0,0xa0,0x40,0x00, 4, // 0x56 'V' 0x00,0xa0,0xa0,0xa0,0xa0,0x40,0x40,0x00, 4, // 0x57 'W' 0x00,0xa0,0xa0,0xa0,0xa0,0xe0,0xa0,0x00, 4, // 0x58 'X' 0x00,0xa0,0xa0,0x40,0xa0,0xa0,0xa0,0x00, 4, // 0x59 'Y' 0x00,0xa0,0xa0,0x40,0x40,0x40,0x40,0x00, 4, // 0x5a 'Z' 0x00,0xe0,0x20,0x40,0x40,0x80,0xe0,0x00, 4, // 0x5b '[' 0xc0,0x80,0x80,0x80,0x80,0x80,0x80,0xc0, 4, // 0x5c '\' 0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10, 4, // 0x5d ']' 0xc0,0x40,0x40,0x40,0x40,0x40,0x40,0xc0, 4, // 0x5e '^' 0x00,0x40,0xa0,0x00,0x00,0x00,0x00,0x00, 4, // 0x5f '_' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0, 4, // 0x60 '`' 0x00,0x40,0x20,0x00,0x00,0x00,0x00,0x00, 4, // 0x61 'a' 0x00,0x00,0x60,0xa0,0xa0,0xa0,0x70,0x00, 4, // 0x62 'b' 0x00,0x80,0x80,0xc0,0xa0,0xa0,0xc0,0x00, 4, // 0x63 'c' 0x00,0x00,0x40,0xa0,0x80,0xa0,0x40,0x00, 4, // 0x64 'd' 0x00,0x20,0x20,0x60,0xa0,0xa0,0x60,0x00, 4, // 0x65 'e' 0x00,0x00,0x40,0xa0,0xe0,0x80,0x60,0x00, 4, // 0x66 'f' 0x00,0x20,0x40,0x40,0xe0,0x40,0x40,0x00, 4, // 0x67 'g' 0x00,0x00,0x60,0xa0,0xa0,0x60,0x20,0xc0, 4, // 0x68 'h' 0x00,0x80,0x80,0xc0,0xa0,0xa0,0xa0,0x00, 4, // 0x69 'i' 0x00,0x40,0x00,0xc0,0x40,0x40,0xe0,0x00, 4, // 0x6a 'j' 0x00,0x40,0x00,0xc0,0x40,0x40,0x40,0x80, 4, // 0x6b 'k' 0x00,0x80,0x80,0xa0,0xc0,0xc0,0xa0,0x00, 4, // 0x6c 'l' 0x00,0xc0,0x40,0x40,0x40,0x40,0xe0,0x00, 4, // 0x6d 'm' 0x00,0x00,0xa0,0xf0,0xf0,0xf0,0x90,0x00, 4, // 0x6e 'n' 0x00,0x00,0xc0,0xa0,0xa0,0xa0,0xa0,0x00, 4, // 0x6f 'o' 0x00,0x00,0x40,0xa0,0xa0,0xa0,0x40,0x00, 4, // 0x70 'p' 0x00,0x00,0xc0,0xa0,0xa0,0xc0,0x80,0x80, 4, // 0x71 'q' 0x00,0x00,0x60,0xa0,0xa0,0x60,0x20,0x20, 4, // 0x72 'r' 0x00,0x00,0xa0,0x50,0x40,0x40,0x40,0x00, 4, // 0x73 's' 0x00,0x00,0x60,0x80,0x40,0x20,0xc0,0x00, 4, // 0x74 't' 0x00,0x40,0x40,0xe0,0x40,0x40,0x20,0x00, 4, // 0x75 'u' 0x00,0x00,0xa0,0xa0,0xa0,0xa0,0x60,0x00, 4, // 0x76 'v' 0x00,0x00,0xa0,0xa0,0xa0,0x40,0x40,0x00, 4, // 0x77 'w' 0x00,0x00,0xa0,0xa0,0xa0,0xe0,0xa0,0x00, 4, // 0x78 'x' 0x00,0x00,0xa0,0xa0,0x40,0xa0,0xa0,0x00, 4, // 0x79 'y' 0x00,0x00,0xa0,0xa0,0xa0,0x60,0x20,0xc0, 4, // 0x7a 'z' 0x00,0x00,0xe0,0x20,0x40,0x80,0xe0,0x00, 4, // 0x7b '{' 0x10,0x20,0x20,0xc0,0x20,0x20,0x10,0x00, 4, // 0x7c '|' 0x00,0x40,0x40,0x40,0x00,0x40,0x40,0x40, 4, // 0x7d '}' 0x80,0x40,0x40,0x30,0x40,0x40,0x80,0x00, 4, // 0x7e '~' 0x00,0x50,0xa0,0x00,0x00,0x00,0x00,0x00, 4, // 0x7f '' 0x00,0x00,0x00,0x60,0x90,0xf0,0x00,0x00, 0 }; const int8u gse5x7[] = { 7, 0, 32, 128-32, 0x00,0x00,0x08,0x00,0x10,0x00,0x18,0x00,0x20,0x00,0x28,0x00,0x30,0x00,0x38,0x00,0x40,0x00, 0x48,0x00,0x50,0x00,0x58,0x00,0x60,0x00,0x68,0x00,0x70,0x00,0x78,0x00,0x80,0x00,0x88,0x00, 0x90,0x00,0x98,0x00,0xa0,0x00,0xa8,0x00,0xb0,0x00,0xb8,0x00,0xc0,0x00,0xc8,0x00,0xd0,0x00, 0xd8,0x00,0xe0,0x00,0xe8,0x00,0xf0,0x00,0xf8,0x00,0x00,0x01,0x08,0x01,0x10,0x01,0x18,0x01, 0x20,0x01,0x28,0x01,0x30,0x01,0x38,0x01,0x40,0x01,0x48,0x01,0x50,0x01,0x58,0x01,0x60,0x01, 0x68,0x01,0x70,0x01,0x78,0x01,0x80,0x01,0x88,0x01,0x90,0x01,0x98,0x01,0xa0,0x01,0xa8,0x01, 0xb0,0x01,0xb8,0x01,0xc0,0x01,0xc8,0x01,0xd0,0x01,0xd8,0x01,0xe0,0x01,0xe8,0x01,0xf0,0x01, 0xf8,0x01,0x00,0x02,0x08,0x02,0x10,0x02,0x18,0x02,0x20,0x02,0x28,0x02,0x30,0x02,0x38,0x02, 0x40,0x02,0x48,0x02,0x50,0x02,0x58,0x02,0x60,0x02,0x68,0x02,0x70,0x02,0x78,0x02,0x80,0x02, 0x88,0x02,0x90,0x02,0x98,0x02,0xa0,0x02,0xa8,0x02,0xb0,0x02,0xb8,0x02,0xc0,0x02,0xc8,0x02, 0xd0,0x02,0xd8,0x02,0xe0,0x02,0xe8,0x02,0xf0,0x02,0xf8,0x02, 5, // 0x20 ' ' 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x21 '!' 0x00,0x20,0x20,0x20,0x00,0x20,0x00, 5, // 0x22 '"' 0x00,0x50,0x50,0x00,0x00,0x00,0x00, 5, // 0x23 '#' 0x00,0x50,0xf8,0x50,0xf8,0x50,0x00, 5, // 0x24 '$' 0x20,0x78,0xa0,0x70,0x28,0xf0,0x20, 5, // 0x25 '%' 0x00,0x88,0x10,0x20,0x40,0x88,0x00, 5, // 0x26 '&' 0x00,0x40,0xa0,0x68,0x90,0x68,0x00, 5, // 0x27 ''' 0x00,0x20,0x20,0x00,0x00,0x00,0x00, 5, // 0x28 '(' 0x10,0x20,0x40,0x40,0x40,0x20,0x10, 5, // 0x29 ')' 0x80,0x40,0x20,0x20,0x20,0x40,0x80, 5, // 0x2a '*' 0x00,0x20,0xa8,0x70,0xa8,0x20,0x00, 5, // 0x2b '+' 0x00,0x20,0x20,0xf8,0x20,0x20,0x00, 5, // 0x2c ',' 0x00,0x00,0x00,0x00,0x20,0x20,0x40, 5, // 0x2d '-' 0x00,0x00,0x00,0xf0,0x00,0x00,0x00, 5, // 0x2e '.' 0x00,0x00,0x00,0x00,0x00,0x40,0x00, 5, // 0x2f '/' 0x00,0x08,0x10,0x20,0x40,0x80,0x00, 5, // 0x30 '0' 0x00,0x60,0x90,0x90,0x90,0x60,0x00, 5, // 0x31 '1' 0x00,0x20,0x60,0x20,0x20,0x70,0x00, 5, // 0x32 '2' 0x00,0x60,0x90,0x20,0x40,0xf0,0x00, 5, // 0x33 '3' 0x00,0xf0,0x20,0x60,0x10,0xe0,0x00, 5, // 0x34 '4' 0x00,0x30,0x50,0x90,0xf0,0x10,0x00, 5, // 0x35 '5' 0x00,0xf0,0x80,0xe0,0x10,0xe0,0x00, 5, // 0x36 '6' 0x00,0x60,0x80,0xe0,0x90,0x60,0x00, 5, // 0x37 '7' 0x00,0xf0,0x90,0x20,0x40,0x40,0x00, 5, // 0x38 '8' 0x00,0x60,0x90,0x60,0x90,0x60,0x00, 5, // 0x39 '9' 0x00,0x60,0x90,0x70,0x10,0x60,0x00, 5, // 0x3a ':' 0x00,0x00,0x20,0x00,0x20,0x00,0x00, 5, // 0x3b ';' 0x00,0x00,0x20,0x00,0x20,0x20,0x40, 5, // 0x3c '<' 0x00,0x10,0x20,0x40,0x20,0x10,0x00, 5, // 0x3d '=' 0x00,0x00,0xf0,0x00,0xf0,0x00,0x00, 5, // 0x3e '>' 0x00,0x80,0x40,0x20,0x40,0x80,0x00, 5, // 0x3f '?' 0x00,0x60,0x90,0x20,0x00,0x20,0x00, 5, // 0x40 '@' 0x00,0x60,0x90,0xb0,0x80,0x70,0x00, 5, // 0x41 'A' 0x00,0x60,0x90,0xf0,0x90,0x90,0x00, 5, // 0x42 'B' 0x00,0xe0,0x90,0xe0,0x90,0xe0,0x00, 5, // 0x43 'C' 0x00,0x60,0x90,0x80,0x90,0x60,0x00, 5, // 0x44 'D' 0x00,0xe0,0x90,0x90,0x90,0xe0,0x00, 5, // 0x45 'E' 0x00,0xf0,0x80,0xe0,0x80,0xf0,0x00, 5, // 0x46 'F' 0x00,0xf0,0x80,0xe0,0x80,0x80,0x00, 5, // 0x47 'G' 0x00,0x70,0x80,0xb0,0x90,0x60,0x00, 5, // 0x48 'H' 0x00,0x90,0x90,0xf0,0x90,0x90,0x00, 5, // 0x49 'I' 0x00,0x70,0x20,0x20,0x20,0x70,0x00, 5, // 0x4a 'J' 0x00,0x70,0x20,0x20,0xa0,0x40,0x00, 5, // 0x4b 'K' 0x00,0x90,0xa0,0xc0,0xa0,0x90,0x00, 5, // 0x4c 'L' 0x00,0x80,0x80,0x80,0x80,0xf0,0x00, 5, // 0x4d 'M' 0x00,0x90,0xf0,0x90,0x90,0x90,0x00, 5, // 0x4e 'N' 0x00,0x90,0xd0,0xb0,0x90,0x90,0x00, 5, // 0x4f 'O' 0x00,0x60,0x90,0x90,0x90,0x60,0x00, 5, // 0x50 'P' 0x00,0xe0,0x90,0xe0,0x80,0x80,0x00, 5, // 0x51 'Q' 0x00,0x60,0x90,0x90,0xa0,0x50,0x00, 5, // 0x52 'R' 0x00,0xe0,0x90,0xe0,0xa0,0x90,0x00, 5, // 0x53 'S' 0x00,0x70,0x80,0x60,0x10,0xe0,0x00, 5, // 0x54 'T' 0x00,0x70,0x20,0x20,0x20,0x20,0x00, 5, // 0x55 'U' 0x00,0x90,0x90,0x90,0x90,0x60,0x00, 5, // 0x56 'V' 0x00,0x50,0x50,0x50,0x20,0x20,0x00, 5, // 0x57 'W' 0x00,0x90,0x90,0x90,0xf0,0x90,0x00, 5, // 0x58 'X' 0x00,0x90,0x90,0x60,0x90,0x90,0x00, 5, // 0x59 'Y' 0x00,0x50,0x50,0x20,0x20,0x20,0x00, 5, // 0x5a 'Z' 0x00,0xf0,0x10,0x20,0x40,0xf0,0x00, 5, // 0x5b '[' 0x70,0x40,0x40,0x40,0x40,0x40,0x70, 5, // 0x5c '\' 0x00,0x80,0x40,0x20,0x10,0x08,0x00, 5, // 0x5d ']' 0xe0,0x20,0x20,0x20,0x20,0x20,0xe0, 5, // 0x5e '^' 0x00,0x20,0x50,0x00,0x00,0x00,0x00, 5, // 0x5f '_' 0x00,0x00,0x00,0x00,0x00,0xf8,0x00, 5, // 0x60 '`' 0x00,0x40,0x20,0x00,0x00,0x00,0x00, 5, // 0x61 'a' 0x00,0x00,0x60,0xa0,0xa0,0x50,0x00, 5, // 0x62 'b' 0x00,0x80,0x80,0xe0,0x90,0xe0,0x00, 5, // 0x63 'c' 0x00,0x00,0x70,0x80,0x80,0x70,0x00, 5, // 0x64 'd' 0x00,0x10,0x10,0x70,0x90,0x70,0x00, 5, // 0x65 'e' 0x00,0x00,0x60,0xf0,0x80,0x70,0x00, 5, // 0x66 'f' 0x00,0x30,0x40,0xe0,0x40,0x40,0x00, 5, // 0x67 'g' 0x00,0x00,0x70,0x90,0x70,0x10,0x60, 5, // 0x68 'h' 0x00,0x80,0x80,0xe0,0x90,0x90,0x00, 5, // 0x69 'i' 0x20,0x00,0x60,0x20,0x20,0x70,0x00, 5, // 0x6a 'j' 0x20,0x00,0x60,0x20,0x20,0xa0,0x40, 5, // 0x6b 'k' 0x80,0x80,0x90,0xa0,0xe0,0x90,0x00, 5, // 0x6c 'l' 0x00,0x60,0x20,0x20,0x20,0x70,0x00, 5, // 0x6d 'm' 0x00,0x00,0xa0,0xf0,0xf0,0x90,0x00, 5, // 0x6e 'n' 0x00,0x00,0xa0,0xd0,0x90,0x90,0x00, 5, // 0x6f 'o' 0x00,0x00,0x60,0x90,0x90,0x60,0x00, 5, // 0x70 'p' 0x00,0x00,0xe0,0x90,0xe0,0x80,0x80, 5, // 0x71 'q' 0x00,0x00,0x70,0x90,0x70,0x10,0x10, 5, // 0x72 'r' 0x00,0x00,0xe0,0x90,0x80,0x80,0x00, 5, // 0x73 's' 0x00,0x00,0x70,0xe0,0x10,0xe0,0x00, 5, // 0x74 't' 0x40,0x40,0xe0,0x40,0x40,0x70,0x00, 5, // 0x75 'u' 0x00,0x00,0x90,0x90,0x90,0x70,0x00, 5, // 0x76 'v' 0x00,0x00,0x50,0x50,0x50,0x20,0x00, 5, // 0x77 'w' 0x00,0x00,0x90,0x90,0xf0,0x90,0x00, 5, // 0x78 'x' 0x00,0x00,0x90,0x60,0x60,0x90,0x00, 5, // 0x79 'y' 0x00,0x00,0x90,0x90,0x70,0x10,0x60, 5, // 0x7a 'z' 0x00,0x00,0xf0,0x20,0x40,0xf0,0x00, 5, // 0x7b '{' 0x10,0x20,0x20,0xc0,0x20,0x20,0x10, 5, // 0x7c '|' 0x20,0x20,0x20,0x00,0x20,0x20,0x20, 5, // 0x7d '}' 0x40,0x20,0x20,0x18,0x20,0x20,0x40, 5, // 0x7e '~' 0x00,0x40,0xa8,0x10,0x00,0x00,0x00, 5, // 0x7f '' 0x00,0x00,0x20,0x50,0x88,0xf8,0x00, 0 }; const int8u gse5x9[] = { 9, 0, 32, 128-32, 0x00,0x00,0x0a,0x00,0x14,0x00,0x1e,0x00,0x28,0x00,0x32,0x00,0x3c,0x00,0x46,0x00,0x50,0x00, 0x5a,0x00,0x64,0x00,0x6e,0x00,0x78,0x00,0x82,0x00,0x8c,0x00,0x96,0x00,0xa0,0x00,0xaa,0x00, 0xb4,0x00,0xbe,0x00,0xc8,0x00,0xd2,0x00,0xdc,0x00,0xe6,0x00,0xf0,0x00,0xfa,0x00,0x04,0x01, 0x0e,0x01,0x18,0x01,0x22,0x01,0x2c,0x01,0x36,0x01,0x40,0x01,0x4a,0x01,0x54,0x01,0x5e,0x01, 0x68,0x01,0x72,0x01,0x7c,0x01,0x86,0x01,0x90,0x01,0x9a,0x01,0xa4,0x01,0xae,0x01,0xb8,0x01, 0xc2,0x01,0xcc,0x01,0xd6,0x01,0xe0,0x01,0xea,0x01,0xf4,0x01,0xfe,0x01,0x08,0x02,0x12,0x02, 0x1c,0x02,0x26,0x02,0x30,0x02,0x3a,0x02,0x44,0x02,0x4e,0x02,0x58,0x02,0x62,0x02,0x6c,0x02, 0x76,0x02,0x80,0x02,0x8a,0x02,0x94,0x02,0x9e,0x02,0xa8,0x02,0xb2,0x02,0xbc,0x02,0xc6,0x02, 0xd0,0x02,0xda,0x02,0xe4,0x02,0xee,0x02,0xf8,0x02,0x02,0x03,0x0c,0x03,0x16,0x03,0x20,0x03, 0x2a,0x03,0x34,0x03,0x3e,0x03,0x48,0x03,0x52,0x03,0x5c,0x03,0x66,0x03,0x70,0x03,0x7a,0x03, 0x84,0x03,0x8e,0x03,0x98,0x03,0xa2,0x03,0xac,0x03,0xb6,0x03, 5, // 0x20 ' ' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x21 '!' 0x00,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00, 5, // 0x22 '"' 0x00,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x23 '#' 0x00,0x50,0x50,0xf8,0x50,0xf8,0x50,0x50,0x00, 5, // 0x24 '$' 0x00,0x20,0x78,0xa0,0x70,0x28,0xf0,0x20,0x00, 5, // 0x25 '%' 0x00,0xc8,0xc8,0x10,0x20,0x40,0x98,0x98,0x00, 5, // 0x26 '&' 0x00,0x40,0xa0,0xa0,0x40,0xa8,0x90,0x68,0x00, 5, // 0x27 ''' 0x00,0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x28 '(' 0x10,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x10, 5, // 0x29 ')' 0x80,0x40,0x20,0x20,0x20,0x20,0x20,0x40,0x80, 5, // 0x2a '*' 0x00,0x00,0x20,0xa8,0x70,0xa8,0x20,0x00,0x00, 5, // 0x2b '+' 0x00,0x00,0x20,0x20,0xf8,0x20,0x20,0x00,0x00, 5, // 0x2c ',' 0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x40, 5, // 0x2d '-' 0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00, 5, // 0x2e '.' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00, 5, // 0x2f '/' 0x00,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x80, 5, // 0x30 '0' 0x00,0x60,0x90,0xb0,0xd0,0x90,0x90,0x60,0x00, 5, // 0x31 '1' 0x00,0x20,0x60,0x20,0x20,0x20,0x20,0x70,0x00, 5, // 0x32 '2' 0x00,0x60,0x90,0x10,0x20,0x40,0x80,0xf0,0x00, 5, // 0x33 '3' 0x00,0xf0,0x10,0x20,0x60,0x10,0x90,0x60,0x00, 5, // 0x34 '4' 0x00,0x30,0x50,0x90,0x90,0xf8,0x10,0x10,0x00, 5, // 0x35 '5' 0x00,0xf0,0x80,0xe0,0x10,0x10,0x10,0xe0,0x00, 5, // 0x36 '6' 0x00,0x60,0x80,0xe0,0x90,0x90,0x90,0x60,0x00, 5, // 0x37 '7' 0x00,0xf0,0x90,0x10,0x20,0x40,0x40,0x40,0x00, 5, // 0x38 '8' 0x00,0x60,0x90,0x90,0x60,0x90,0x90,0x60,0x00, 5, // 0x39 '9' 0x00,0x60,0x90,0x90,0x70,0x10,0x90,0x60,0x00, 5, // 0x3a ':' 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x00,0x00, 5, // 0x3b ';' 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x20,0x40, 5, // 0x3c '<' 0x00,0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x00, 5, // 0x3d '=' 0x00,0x00,0x00,0xf0,0x00,0xf0,0x00,0x00,0x00, 5, // 0x3e '>' 0x00,0x80,0x40,0x20,0x10,0x20,0x40,0x80,0x00, 5, // 0x3f '?' 0x00,0x60,0x90,0x10,0x20,0x20,0x00,0x20,0x00, 5, // 0x40 '@' 0x00,0x60,0x90,0xb0,0xb0,0xb0,0x80,0x70,0x00, 5, // 0x41 'A' 0x00,0x60,0x90,0x90,0xf0,0x90,0x90,0x90,0x00, 5, // 0x42 'B' 0x00,0xe0,0x90,0x90,0xe0,0x90,0x90,0xe0,0x00, 5, // 0x43 'C' 0x00,0x60,0x90,0x80,0x80,0x80,0x90,0x60,0x00, 5, // 0x44 'D' 0x00,0xe0,0x90,0x90,0x90,0x90,0x90,0xe0,0x00, 5, // 0x45 'E' 0x00,0xf0,0x80,0x80,0xe0,0x80,0x80,0xf0,0x00, 5, // 0x46 'F' 0x00,0xf0,0x80,0x80,0xe0,0x80,0x80,0x80,0x00, 5, // 0x47 'G' 0x00,0x60,0x90,0x80,0xb0,0x90,0x90,0x60,0x00, 5, // 0x48 'H' 0x00,0x90,0x90,0x90,0xf0,0x90,0x90,0x90,0x00, 5, // 0x49 'I' 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00, 5, // 0x4a 'J' 0x00,0x70,0x20,0x20,0x20,0x20,0xa0,0x40,0x00, 5, // 0x4b 'K' 0x00,0x90,0x90,0xa0,0xc0,0xa0,0x90,0x90,0x00, 5, // 0x4c 'L' 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0xf0,0x00, 5, // 0x4d 'M' 0x00,0x90,0xf0,0x90,0x90,0x90,0x90,0x90,0x00, 5, // 0x4e 'N' 0x00,0x90,0x90,0xd0,0xb0,0x90,0x90,0x90,0x00, 5, // 0x4f 'O' 0x00,0x60,0x90,0x90,0x90,0x90,0x90,0x60,0x00, 5, // 0x50 'P' 0x00,0xe0,0x90,0x90,0xe0,0x80,0x80,0x80,0x00, 5, // 0x51 'Q' 0x00,0x60,0x90,0x90,0x90,0x90,0xa0,0x50,0x00, 5, // 0x52 'R' 0x00,0xe0,0x90,0x90,0xe0,0xa0,0x90,0x90,0x00, 5, // 0x53 'S' 0x00,0x60,0x90,0x80,0x60,0x10,0x90,0x60,0x00, 5, // 0x54 'T' 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x00, 5, // 0x55 'U' 0x00,0x90,0x90,0x90,0x90,0x90,0x90,0x60,0x00, 5, // 0x56 'V' 0x00,0x50,0x50,0x50,0x50,0x50,0x20,0x20,0x00, 5, // 0x57 'W' 0x00,0x90,0x90,0x90,0x90,0x90,0xf0,0x90,0x00, 5, // 0x58 'X' 0x00,0x90,0x90,0x60,0x60,0x90,0x90,0x90,0x00, 5, // 0x59 'Y' 0x00,0x50,0x50,0x50,0x20,0x20,0x20,0x20,0x00, 5, // 0x5a 'Z' 0x00,0xf0,0x10,0x10,0x20,0x40,0x80,0xf0,0x00, 5, // 0x5b '[' 0x70,0x40,0x40,0x40,0x40,0x40,0x40,0x70,0x00, 5, // 0x5c '\' 0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x00, 5, // 0x5d ']' 0xe0,0x20,0x20,0x20,0x20,0x20,0x20,0xe0,0x00, 5, // 0x5e '^' 0x00,0x20,0x50,0x88,0x00,0x00,0x00,0x00,0x00, 5, // 0x5f '_' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x00, 5, // 0x60 '`' 0x00,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x61 'a' 0x00,0x00,0x60,0x10,0x70,0x90,0x90,0x70,0x00, 5, // 0x62 'b' 0x00,0x80,0x80,0xe0,0x90,0x90,0x90,0xe0,0x00, 5, // 0x63 'c' 0x00,0x00,0x60,0x90,0x80,0x80,0x90,0x60,0x00, 5, // 0x64 'd' 0x00,0x10,0x10,0x70,0x90,0x90,0x90,0x70,0x00, 5, // 0x65 'e' 0x00,0x00,0x60,0x90,0xf0,0x80,0x80,0x70,0x00, 5, // 0x66 'f' 0x00,0x30,0x40,0x40,0xe0,0x40,0x40,0x40,0x00, 5, // 0x67 'g' 0x00,0x00,0x70,0x90,0x90,0x70,0x10,0x90,0x60, 5, // 0x68 'h' 0x00,0x80,0x80,0xe0,0x90,0x90,0x90,0x90,0x00, 5, // 0x69 'i' 0x00,0x20,0x00,0x60,0x20,0x20,0x20,0x70,0x00, 5, // 0x6a 'j' 0x00,0x20,0x00,0x60,0x20,0x20,0x20,0xa0,0x40, 5, // 0x6b 'k' 0x00,0x80,0x80,0x90,0xa0,0xc0,0xa0,0x90,0x00, 5, // 0x6c 'l' 0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x70,0x00, 5, // 0x6d 'm' 0x00,0x00,0xa0,0xf0,0xf0,0xf0,0x90,0x90,0x00, 5, // 0x6e 'n' 0x00,0x00,0xa0,0xd0,0x90,0x90,0x90,0x90,0x00, 5, // 0x6f 'o' 0x00,0x00,0x60,0x90,0x90,0x90,0x90,0x60,0x00, 5, // 0x70 'p' 0x00,0x00,0xe0,0x90,0x90,0x90,0xe0,0x80,0x80, 5, // 0x71 'q' 0x00,0x00,0x70,0x90,0x90,0x90,0x70,0x10,0x10, 5, // 0x72 'r' 0x00,0x00,0xe0,0x90,0x80,0x80,0x80,0x80,0x00, 5, // 0x73 's' 0x00,0x00,0x60,0x90,0x40,0x20,0x90,0x60,0x00, 5, // 0x74 't' 0x00,0x40,0x40,0xe0,0x40,0x40,0x50,0x20,0x00, 5, // 0x75 'u' 0x00,0x00,0x90,0x90,0x90,0x90,0x90,0x70,0x00, 5, // 0x76 'v' 0x00,0x00,0x50,0x50,0x50,0x50,0x20,0x20,0x00, 5, // 0x77 'w' 0x00,0x00,0x90,0x90,0x90,0x90,0xf0,0x90,0x00, 5, // 0x78 'x' 0x00,0x00,0x90,0x90,0x60,0x60,0x90,0x90,0x00, 5, // 0x79 'y' 0x00,0x00,0x90,0x90,0x90,0x90,0x70,0x10,0xe0, 5, // 0x7a 'z' 0x00,0x00,0xf0,0x10,0x20,0x40,0x80,0xf0,0x00, 5, // 0x7b '{' 0x10,0x20,0x20,0x20,0xc0,0x20,0x20,0x20,0x10, 5, // 0x7c '|' 0x00,0x20,0x20,0x20,0x00,0x20,0x20,0x20,0x00, 5, // 0x7d '}' 0x80,0x40,0x40,0x40,0x30,0x40,0x40,0x40,0x80, 5, // 0x7e '~' 0x00,0x40,0xa8,0x10,0x00,0x00,0x00,0x00,0x00, 5, // 0x7f '' 0x00,0x00,0x00,0x20,0x50,0x88,0xf8,0x00,0x00, 0 }; const int8u gse6x12[] = { 12, 0, 32, 128-32, 0x00,0x00,0x0d,0x00,0x1a,0x00,0x27,0x00,0x34,0x00,0x41,0x00,0x4e,0x00,0x5b,0x00,0x68,0x00, 0x75,0x00,0x82,0x00,0x8f,0x00,0x9c,0x00,0xa9,0x00,0xb6,0x00,0xc3,0x00,0xd0,0x00,0xdd,0x00, 0xea,0x00,0xf7,0x00,0x04,0x01,0x11,0x01,0x1e,0x01,0x2b,0x01,0x38,0x01,0x45,0x01,0x52,0x01, 0x5f,0x01,0x6c,0x01,0x79,0x01,0x86,0x01,0x93,0x01,0xa0,0x01,0xad,0x01,0xba,0x01,0xc7,0x01, 0xd4,0x01,0xe1,0x01,0xee,0x01,0xfb,0x01,0x08,0x02,0x15,0x02,0x22,0x02,0x2f,0x02,0x3c,0x02, 0x49,0x02,0x56,0x02,0x63,0x02,0x70,0x02,0x7d,0x02,0x8a,0x02,0x97,0x02,0xa4,0x02,0xb1,0x02, 0xbe,0x02,0xcb,0x02,0xd8,0x02,0xe5,0x02,0xf2,0x02,0xff,0x02,0x0c,0x03,0x19,0x03,0x26,0x03, 0x33,0x03,0x40,0x03,0x4d,0x03,0x5a,0x03,0x67,0x03,0x74,0x03,0x81,0x03,0x8e,0x03,0x9b,0x03, 0xa8,0x03,0xb5,0x03,0xc2,0x03,0xcf,0x03,0xdc,0x03,0xe9,0x03,0xf6,0x03,0x03,0x04,0x10,0x04, 0x1d,0x04,0x2a,0x04,0x37,0x04,0x44,0x04,0x51,0x04,0x5e,0x04,0x6b,0x04,0x78,0x04,0x85,0x04, 0x92,0x04,0x9f,0x04,0xac,0x04,0xb9,0x04,0xc6,0x04,0xd3,0x04, 6, // 0x20 ' ' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x21 '!' 0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00, 6, // 0x22 '"' 0x00,0x50,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x23 '#' 0x00,0x50,0x50,0xf8,0x50,0x50,0x50,0xf8,0x50,0x50,0x00,0x00, 6, // 0x24 '$' 0x00,0x20,0x70,0xa8,0xa0,0x70,0x28,0xa8,0x70,0x20,0x00,0x00, 6, // 0x25 '%' 0x00,0xc8,0xd8,0x10,0x30,0x20,0x60,0x40,0xd8,0x98,0x00,0x00, 6, // 0x26 '&' 0x00,0x60,0x90,0x90,0x90,0x60,0xa8,0x90,0x90,0x68,0x00,0x00, 6, // 0x27 ''' 0x00,0x20,0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x28 '(' 0x00,0x10,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x10,0x00,0x00, 6, // 0x29 ')' 0x00,0x40,0x20,0x10,0x10,0x10,0x10,0x10,0x20,0x40,0x00,0x00, 6, // 0x2a '*' 0x00,0x00,0x00,0x50,0x20,0xf8,0x20,0x50,0x00,0x00,0x00,0x00, 6, // 0x2b '+' 0x00,0x00,0x20,0x20,0x20,0xf8,0x20,0x20,0x20,0x00,0x00,0x00, 6, // 0x2c ',' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x40, 6, // 0x2d '-' 0x00,0x00,0x00,0x00,0x00,0xf8,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x2e '.' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00, 6, // 0x2f '/' 0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x80,0x00,0x00, 6, // 0x30 '0' 0x00,0x70,0x88,0x88,0x98,0xa8,0xc8,0x88,0x88,0x70,0x00,0x00, 6, // 0x31 '1' 0x00,0x20,0x20,0x60,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, 6, // 0x32 '2' 0x00,0x70,0x88,0x88,0x08,0x10,0x20,0x40,0x80,0xf8,0x00,0x00, 6, // 0x33 '3' 0x00,0xf8,0x10,0x20,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00, 6, // 0x34 '4' 0x00,0x10,0x20,0x40,0x90,0x90,0xf8,0x10,0x10,0x10,0x00,0x00, 6, // 0x35 '5' 0x00,0xf8,0x80,0x80,0xf0,0x08,0x08,0x08,0x88,0x70,0x00,0x00, 6, // 0x36 '6' 0x00,0x70,0x88,0x80,0x80,0xf0,0x88,0x88,0x88,0x70,0x00,0x00, 6, // 0x37 '7' 0x00,0xf8,0x88,0x08,0x08,0x10,0x20,0x20,0x20,0x20,0x00,0x00, 6, // 0x38 '8' 0x00,0x70,0x88,0x88,0x88,0x70,0x88,0x88,0x88,0x70,0x00,0x00, 6, // 0x39 '9' 0x00,0x70,0x88,0x88,0x88,0x78,0x08,0x08,0x88,0x70,0x00,0x00, 6, // 0x3a ':' 0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00, 6, // 0x3b ';' 0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x20,0x20,0x40, 6, // 0x3c '<' 0x00,0x08,0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x08,0x00,0x00, 6, // 0x3d '=' 0x00,0x00,0x00,0x00,0xf8,0x00,0xf8,0x00,0x00,0x00,0x00,0x00, 6, // 0x3e '>' 0x00,0x80,0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x80,0x00,0x00, 6, // 0x3f '?' 0x00,0x70,0x88,0x88,0x08,0x10,0x20,0x20,0x00,0x20,0x00,0x00, 6, // 0x40 '@' 0x00,0x70,0x88,0x88,0xb8,0xb8,0xb0,0x80,0x88,0x70,0x00,0x00, 6, // 0x41 'A' 0x00,0x20,0x50,0x88,0x88,0x88,0xf8,0x88,0x88,0x88,0x00,0x00, 6, // 0x42 'B' 0x00,0xf0,0x88,0x88,0x88,0xf0,0x88,0x88,0x88,0xf0,0x00,0x00, 6, // 0x43 'C' 0x00,0x70,0x88,0x88,0x80,0x80,0x80,0x88,0x88,0x70,0x00,0x00, 6, // 0x44 'D' 0x00,0xe0,0x90,0x88,0x88,0x88,0x88,0x88,0x90,0xe0,0x00,0x00, 6, // 0x45 'E' 0x00,0xf8,0x80,0x80,0x80,0xf0,0x80,0x80,0x80,0xf8,0x00,0x00, 6, // 0x46 'F' 0x00,0xf8,0x80,0x80,0x80,0xf0,0x80,0x80,0x80,0x80,0x00,0x00, 6, // 0x47 'G' 0x00,0x70,0x88,0x80,0x80,0xb8,0x88,0x88,0x88,0x70,0x00,0x00, 6, // 0x48 'H' 0x00,0x88,0x88,0x88,0x88,0xf8,0x88,0x88,0x88,0x88,0x00,0x00, 6, // 0x49 'I' 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, 6, // 0x4a 'J' 0x00,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x90,0x60,0x00,0x00, 6, // 0x4b 'K' 0x00,0x88,0x88,0x90,0xa0,0xc0,0xa0,0x90,0x88,0x88,0x00,0x00, 6, // 0x4c 'L' 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xf8,0x00,0x00, 6, // 0x4d 'M' 0x00,0x88,0x88,0xd8,0xa8,0x88,0x88,0x88,0x88,0x88,0x00,0x00, 6, // 0x4e 'N' 0x00,0x88,0x88,0xc8,0xa8,0x98,0x88,0x88,0x88,0x88,0x00,0x00, 6, // 0x4f 'O' 0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, 6, // 0x50 'P' 0x00,0xf0,0x88,0x88,0x88,0xf0,0x80,0x80,0x80,0x80,0x00,0x00, 6, // 0x51 'Q' 0x00,0x70,0x88,0x88,0x88,0x88,0x88,0xa8,0x90,0x68,0x00,0x00, 6, // 0x52 'R' 0x00,0xf0,0x88,0x88,0x88,0x88,0xf0,0xa0,0x90,0x88,0x00,0x00, 6, // 0x53 'S' 0x00,0x70,0x88,0x80,0x80,0x70,0x08,0x08,0x88,0x70,0x00,0x00, 6, // 0x54 'T' 0x00,0xf8,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00, 6, // 0x55 'U' 0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, 6, // 0x56 'V' 0x00,0x88,0x88,0x88,0x88,0x88,0x50,0x50,0x20,0x20,0x00,0x00, 6, // 0x57 'W' 0x00,0x88,0x88,0x88,0x88,0x88,0xa8,0xa8,0xd8,0x88,0x00,0x00, 6, // 0x58 'X' 0x00,0x88,0x88,0x88,0x50,0x20,0x50,0x88,0x88,0x88,0x00,0x00, 6, // 0x59 'Y' 0x00,0x88,0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x20,0x00,0x00, 6, // 0x5a 'Z' 0x00,0xf8,0x08,0x08,0x10,0x20,0x40,0x80,0x80,0xf8,0x00,0x00, 6, // 0x5b '[' 0x70,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x70,0x00, 6, // 0x5c '\' 0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x00,0x00, 6, // 0x5d ']' 0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x70,0x00, 6, // 0x5e '^' 0x00,0x00,0x20,0x50,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x5f '_' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x00,0x00, 6, // 0x60 '`' 0x00,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x61 'a' 0x00,0x00,0x00,0x70,0x88,0x08,0x78,0x88,0x88,0x78,0x00,0x00, 6, // 0x62 'b' 0x00,0x80,0x80,0x80,0xf0,0x88,0x88,0x88,0x88,0xf0,0x00,0x00, 6, // 0x63 'c' 0x00,0x00,0x00,0x70,0x88,0x80,0x80,0x80,0x88,0x70,0x00,0x00, 6, // 0x64 'd' 0x00,0x08,0x08,0x08,0x78,0x88,0x88,0x88,0x88,0x78,0x00,0x00, 6, // 0x65 'e' 0x00,0x00,0x00,0x70,0x88,0x88,0xf8,0x80,0x80,0x78,0x00,0x00, 6, // 0x66 'f' 0x00,0x18,0x20,0x20,0xf8,0x20,0x20,0x20,0x20,0x20,0x00,0x00, 6, // 0x67 'g' 0x00,0x00,0x00,0x78,0x88,0x88,0x88,0x88,0x78,0x08,0x08,0xf0, 6, // 0x68 'h' 0x00,0x80,0x80,0x80,0xf0,0x88,0x88,0x88,0x88,0x88,0x00,0x00, 6, // 0x69 'i' 0x00,0x20,0x00,0x00,0x60,0x20,0x20,0x20,0x20,0x70,0x00,0x00, 6, // 0x6a 'j' 0x00,0x10,0x00,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x90,0x60, 6, // 0x6b 'k' 0x00,0x80,0x80,0x80,0x88,0x90,0xa0,0xd0,0x88,0x88,0x00,0x00, 6, // 0x6c 'l' 0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, 6, // 0x6d 'm' 0x00,0x00,0x00,0xd0,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0x00,0x00, 6, // 0x6e 'n' 0x00,0x00,0x00,0xb0,0xc8,0x88,0x88,0x88,0x88,0x88,0x00,0x00, 6, // 0x6f 'o' 0x00,0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, 6, // 0x70 'p' 0x00,0x00,0x00,0xf0,0x88,0x88,0x88,0x88,0xf0,0x80,0x80,0x80, 6, // 0x71 'q' 0x00,0x00,0x00,0x78,0x88,0x88,0x88,0x88,0x78,0x08,0x08,0x08, 6, // 0x72 'r' 0x00,0x00,0x00,0xb0,0xc8,0x88,0x80,0x80,0x80,0x80,0x00,0x00, 6, // 0x73 's' 0x00,0x00,0x00,0x70,0x88,0x80,0x70,0x08,0x88,0x70,0x00,0x00, 6, // 0x74 't' 0x00,0x40,0x40,0x40,0xe0,0x40,0x40,0x40,0x48,0x30,0x00,0x00, 6, // 0x75 'u' 0x00,0x00,0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x78,0x00,0x00, 6, // 0x76 'v' 0x00,0x00,0x00,0x88,0x88,0x88,0x50,0x50,0x20,0x20,0x00,0x00, 6, // 0x77 'w' 0x00,0x00,0x00,0x88,0x88,0x88,0xa8,0xa8,0xd8,0x88,0x00,0x00, 6, // 0x78 'x' 0x00,0x00,0x00,0x88,0x88,0x50,0x20,0x50,0x88,0x88,0x00,0x00, 6, // 0x79 'y' 0x00,0x00,0x00,0x88,0x88,0x88,0x88,0x88,0x78,0x08,0x10,0xe0, 6, // 0x7a 'z' 0x00,0x00,0x00,0xf8,0x08,0x10,0x20,0x40,0x80,0xf8,0x00,0x00, 6, // 0x7b '{' 0x18,0x20,0x20,0x20,0x20,0xc0,0x20,0x20,0x20,0x20,0x18,0x00, 6, // 0x7c '|' 0x00,0x20,0x20,0x20,0x20,0x00,0x20,0x20,0x20,0x20,0x00,0x00, 6, // 0x7d '}' 0xc0,0x20,0x20,0x20,0x20,0x18,0x20,0x20,0x20,0x20,0xc0,0x00, 6, // 0x7e '~' 0x00,0x00,0x40,0xa8,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x7f '' 0x00,0x00,0x00,0x00,0x20,0x50,0x88,0xf8,0x00,0x00,0x00,0x00, 0 }; const int8u gse6x9[] = { 9, 0, 32, 128-32, 0x00,0x00,0x0a,0x00,0x14,0x00,0x1e,0x00,0x28,0x00,0x32,0x00,0x3c,0x00,0x46,0x00,0x50,0x00, 0x5a,0x00,0x64,0x00,0x6e,0x00,0x78,0x00,0x82,0x00,0x8c,0x00,0x96,0x00,0xa0,0x00,0xaa,0x00, 0xb4,0x00,0xbe,0x00,0xc8,0x00,0xd2,0x00,0xdc,0x00,0xe6,0x00,0xf0,0x00,0xfa,0x00,0x04,0x01, 0x0e,0x01,0x18,0x01,0x22,0x01,0x2c,0x01,0x36,0x01,0x40,0x01,0x4a,0x01,0x54,0x01,0x5e,0x01, 0x68,0x01,0x72,0x01,0x7c,0x01,0x86,0x01,0x90,0x01,0x9a,0x01,0xa4,0x01,0xae,0x01,0xb8,0x01, 0xc2,0x01,0xcc,0x01,0xd6,0x01,0xe0,0x01,0xea,0x01,0xf4,0x01,0xfe,0x01,0x08,0x02,0x12,0x02, 0x1c,0x02,0x26,0x02,0x30,0x02,0x3a,0x02,0x44,0x02,0x4e,0x02,0x58,0x02,0x62,0x02,0x6c,0x02, 0x76,0x02,0x80,0x02,0x8a,0x02,0x94,0x02,0x9e,0x02,0xa8,0x02,0xb2,0x02,0xbc,0x02,0xc6,0x02, 0xd0,0x02,0xda,0x02,0xe4,0x02,0xee,0x02,0xf8,0x02,0x02,0x03,0x0c,0x03,0x16,0x03,0x20,0x03, 0x2a,0x03,0x34,0x03,0x3e,0x03,0x48,0x03,0x52,0x03,0x5c,0x03,0x66,0x03,0x70,0x03,0x7a,0x03, 0x84,0x03,0x8e,0x03,0x98,0x03,0xa2,0x03,0xac,0x03,0xb6,0x03, 6, // 0x20 ' ' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x21 '!' 0x00,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00, 6, // 0x22 '"' 0x00,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x23 '#' 0x00,0x50,0x50,0xf8,0x50,0xf8,0x50,0x50,0x00, 6, // 0x24 '$' 0x00,0x70,0xa8,0xa0,0x70,0x28,0xa8,0x70,0x00, 6, // 0x25 '%' 0x00,0xc8,0xc8,0x10,0x20,0x40,0x98,0x98,0x00, 6, // 0x26 '&' 0x00,0x60,0x90,0x90,0x60,0xa8,0x90,0x68,0x00, 6, // 0x27 ''' 0x00,0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x28 '(' 0x10,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x10, 6, // 0x29 ')' 0x40,0x20,0x10,0x10,0x10,0x10,0x10,0x20,0x40, 6, // 0x2a '*' 0x00,0x00,0x20,0xa8,0x70,0xa8,0x20,0x00,0x00, 6, // 0x2b '+' 0x00,0x00,0x20,0x20,0xf8,0x20,0x20,0x00,0x00, 6, // 0x2c ',' 0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x40, 6, // 0x2d '-' 0x00,0x00,0x00,0x00,0xf8,0x00,0x00,0x00,0x00, 6, // 0x2e '.' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00, 6, // 0x2f '/' 0x00,0x08,0x08,0x10,0x20,0x40,0x80,0x80,0x00, 6, // 0x30 '0' 0x00,0x70,0x88,0x98,0xa8,0xc8,0x88,0x70,0x00, 6, // 0x31 '1' 0x00,0x20,0x60,0x20,0x20,0x20,0x20,0x70,0x00, 6, // 0x32 '2' 0x00,0x70,0x88,0x08,0x10,0x20,0x40,0xf8,0x00, 6, // 0x33 '3' 0x00,0xf8,0x10,0x20,0x70,0x08,0x88,0x70,0x00, 6, // 0x34 '4' 0x00,0x10,0x20,0x40,0x90,0xf8,0x10,0x10,0x00, 6, // 0x35 '5' 0x00,0xf8,0x80,0xf0,0x08,0x08,0x88,0x70,0x00, 6, // 0x36 '6' 0x00,0x70,0x88,0x80,0xf0,0x88,0x88,0x70,0x00, 6, // 0x37 '7' 0x00,0xf8,0x08,0x08,0x10,0x20,0x40,0x40,0x00, 6, // 0x38 '8' 0x00,0x70,0x88,0x88,0x70,0x88,0x88,0x70,0x00, 6, // 0x39 '9' 0x00,0x70,0x88,0x88,0x78,0x08,0x88,0x70,0x00, 6, // 0x3a ':' 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x00,0x00, 6, // 0x3b ';' 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x20,0x40, 6, // 0x3c '<' 0x00,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x00, 6, // 0x3d '=' 0x00,0x00,0x00,0xf8,0x00,0xf8,0x00,0x00,0x00, 6, // 0x3e '>' 0x00,0x80,0x40,0x20,0x10,0x20,0x40,0x80,0x00, 6, // 0x3f '?' 0x00,0x70,0x88,0x08,0x10,0x20,0x00,0x20,0x00, 6, // 0x40 '@' 0x00,0x70,0x88,0x88,0xb8,0xb8,0x80,0x70,0x00, 6, // 0x41 'A' 0x00,0x20,0x50,0x88,0x88,0xf8,0x88,0x88,0x00, 6, // 0x42 'B' 0x00,0xf0,0x88,0x88,0xf0,0x88,0x88,0xf0,0x00, 6, // 0x43 'C' 0x00,0x70,0x88,0x80,0x80,0x80,0x88,0x70,0x00, 6, // 0x44 'D' 0x00,0xe0,0x90,0x88,0x88,0x88,0x90,0xe0,0x00, 6, // 0x45 'E' 0x00,0xf8,0x80,0x80,0xf0,0x80,0x80,0xf8,0x00, 6, // 0x46 'F' 0x00,0xf8,0x80,0x80,0xf0,0x80,0x80,0x80,0x00, 6, // 0x47 'G' 0x00,0x70,0x88,0x80,0xb8,0x88,0x88,0x70,0x00, 6, // 0x48 'H' 0x00,0x88,0x88,0x88,0xf8,0x88,0x88,0x88,0x00, 6, // 0x49 'I' 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00, 6, // 0x4a 'J' 0x00,0x38,0x10,0x10,0x10,0x10,0x90,0x60,0x00, 6, // 0x4b 'K' 0x00,0x88,0x90,0xa0,0xc0,0xa0,0x90,0x88,0x00, 6, // 0x4c 'L' 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0xf8,0x00, 6, // 0x4d 'M' 0x00,0x88,0xd8,0xa8,0x88,0x88,0x88,0x88,0x00, 6, // 0x4e 'N' 0x00,0x88,0x88,0xc8,0xa8,0x98,0x88,0x88,0x00, 6, // 0x4f 'O' 0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00, 6, // 0x50 'P' 0x00,0xf0,0x88,0x88,0xf0,0x80,0x80,0x80,0x00, 6, // 0x51 'Q' 0x00,0x70,0x88,0x88,0x88,0xa8,0x90,0x68,0x00, 6, // 0x52 'R' 0x00,0xf0,0x88,0x88,0x88,0xf0,0x90,0x88,0x00, 6, // 0x53 'S' 0x00,0x70,0x88,0x80,0x70,0x08,0x88,0x70,0x00, 6, // 0x54 'T' 0x00,0xf8,0x20,0x20,0x20,0x20,0x20,0x20,0x00, 6, // 0x55 'U' 0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00, 6, // 0x56 'V' 0x00,0x88,0x88,0x88,0x50,0x50,0x20,0x20,0x00, 6, // 0x57 'W' 0x00,0x88,0x88,0x88,0xa8,0xa8,0xd8,0x88,0x00, 6, // 0x58 'X' 0x00,0x88,0x88,0x50,0x20,0x50,0x88,0x88,0x00, 6, // 0x59 'Y' 0x00,0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x00, 6, // 0x5a 'Z' 0x00,0xf8,0x08,0x10,0x20,0x40,0x80,0xf8,0x00, 6, // 0x5b '[' 0x70,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x70, 6, // 0x5c '\' 0x00,0x80,0x80,0x40,0x20,0x10,0x08,0x08,0x00, 6, // 0x5d ']' 0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x70, 6, // 0x5e '^' 0x00,0x00,0x20,0x50,0x88,0x00,0x00,0x00,0x00, 6, // 0x5f '_' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x00, 6, // 0x60 '`' 0x00,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x61 'a' 0x00,0x00,0x00,0x70,0x08,0x78,0x88,0x78,0x00, 6, // 0x62 'b' 0x00,0x80,0x80,0xf0,0x88,0x88,0x88,0xf0,0x00, 6, // 0x63 'c' 0x00,0x00,0x00,0x70,0x88,0x80,0x88,0x70,0x00, 6, // 0x64 'd' 0x00,0x08,0x08,0x78,0x88,0x88,0x88,0x78,0x00, 6, // 0x65 'e' 0x00,0x00,0x00,0x70,0x88,0xf8,0x80,0x78,0x00, 6, // 0x66 'f' 0x00,0x18,0x20,0x20,0xf8,0x20,0x20,0x20,0x00, 6, // 0x67 'g' 0x00,0x00,0x00,0x78,0x88,0x88,0x78,0x08,0x70, 6, // 0x68 'h' 0x00,0x80,0x80,0xf0,0x88,0x88,0x88,0x88,0x00, 6, // 0x69 'i' 0x00,0x20,0x00,0x60,0x20,0x20,0x20,0x70,0x00, 6, // 0x6a 'j' 0x00,0x10,0x00,0x30,0x10,0x10,0x10,0x90,0x60, 6, // 0x6b 'k' 0x00,0x00,0x80,0x88,0x90,0xa0,0xd0,0x88,0x00, 6, // 0x6c 'l' 0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x70,0x00, 6, // 0x6d 'm' 0x00,0x00,0x00,0xd0,0xa8,0xa8,0xa8,0xa8,0x00, 6, // 0x6e 'n' 0x00,0x00,0x00,0xb0,0xc8,0x88,0x88,0x88,0x00, 6, // 0x6f 'o' 0x00,0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x00, 6, // 0x70 'p' 0x00,0x00,0x00,0xf0,0x88,0x88,0xf0,0x80,0x80, 6, // 0x71 'q' 0x00,0x00,0x00,0x78,0x88,0x88,0x78,0x08,0x08, 6, // 0x72 'r' 0x00,0x00,0x00,0xb8,0xc0,0x80,0x80,0x80,0x00, 6, // 0x73 's' 0x00,0x00,0x00,0x78,0x80,0x70,0x08,0xf0,0x00, 6, // 0x74 't' 0x00,0x40,0x40,0xe0,0x40,0x40,0x48,0x30,0x00, 6, // 0x75 'u' 0x00,0x00,0x00,0x88,0x88,0x88,0x88,0x78,0x00, 6, // 0x76 'v' 0x00,0x00,0x00,0x88,0x88,0x88,0x50,0x20,0x00, 6, // 0x77 'w' 0x00,0x00,0x00,0x88,0x88,0xa8,0xd8,0x88,0x00, 6, // 0x78 'x' 0x00,0x00,0x00,0x88,0x50,0x20,0x50,0x88,0x00, 6, // 0x79 'y' 0x00,0x00,0x00,0x88,0x88,0x88,0x78,0x08,0x70, 6, // 0x7a 'z' 0x00,0x00,0x00,0xf8,0x10,0x20,0x40,0xf8,0x00, 6, // 0x7b '{' 0x18,0x20,0x20,0x20,0xc0,0x20,0x20,0x20,0x18, 6, // 0x7c '|' 0x00,0x20,0x20,0x20,0x00,0x20,0x20,0x20,0x00, 6, // 0x7d '}' 0xc0,0x20,0x20,0x20,0x18,0x20,0x20,0x20,0xc0, 6, // 0x7e '~' 0x00,0x40,0xa8,0x10,0x00,0x00,0x00,0x00,0x00, 6, // 0x7f '' 0x00,0x00,0x00,0x20,0x50,0x88,0xf8,0x00,0x00, 0 }; const int8u gse7x11[] = { 11, 0, 32, 128-32, 0x00,0x00,0x0c,0x00,0x18,0x00,0x24,0x00,0x30,0x00,0x3c,0x00,0x48,0x00,0x54,0x00,0x60,0x00, 0x6c,0x00,0x78,0x00,0x84,0x00,0x90,0x00,0x9c,0x00,0xa8,0x00,0xb4,0x00,0xc0,0x00,0xcc,0x00, 0xd8,0x00,0xe4,0x00,0xf0,0x00,0xfc,0x00,0x08,0x01,0x14,0x01,0x20,0x01,0x2c,0x01,0x38,0x01, 0x44,0x01,0x50,0x01,0x5c,0x01,0x68,0x01,0x74,0x01,0x80,0x01,0x8c,0x01,0x98,0x01,0xa4,0x01, 0xb0,0x01,0xbc,0x01,0xc8,0x01,0xd4,0x01,0xe0,0x01,0xec,0x01,0xf8,0x01,0x04,0x02,0x10,0x02, 0x1c,0x02,0x28,0x02,0x34,0x02,0x40,0x02,0x4c,0x02,0x58,0x02,0x64,0x02,0x70,0x02,0x7c,0x02, 0x88,0x02,0x94,0x02,0xa0,0x02,0xac,0x02,0xb8,0x02,0xc4,0x02,0xd0,0x02,0xdc,0x02,0xe8,0x02, 0xf4,0x02,0x00,0x03,0x0c,0x03,0x18,0x03,0x24,0x03,0x30,0x03,0x3c,0x03,0x48,0x03,0x54,0x03, 0x60,0x03,0x6c,0x03,0x78,0x03,0x84,0x03,0x90,0x03,0x9c,0x03,0xa8,0x03,0xb4,0x03,0xc0,0x03, 0xcc,0x03,0xd8,0x03,0xe4,0x03,0xf0,0x03,0xfc,0x03,0x08,0x04,0x14,0x04,0x20,0x04,0x2c,0x04, 0x38,0x04,0x44,0x04,0x50,0x04,0x5c,0x04,0x68,0x04,0x74,0x04, 7, // 0x20 ' ' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x21 '!' 0x00,0x10,0x38,0x38,0x38,0x10,0x10,0x00,0x10,0x00,0x00, 7, // 0x22 '"' 0x00,0x00,0x24,0x24,0x24,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x23 '#' 0x00,0x48,0x48,0xfc,0x48,0x48,0xfc,0x48,0x48,0x00,0x00, 7, // 0x24 '$' 0x00,0x10,0x38,0x54,0x50,0x38,0x14,0x54,0x38,0x10,0x00, 7, // 0x25 '%' 0x00,0x00,0x42,0xa4,0x48,0x10,0x24,0x4a,0x84,0x00,0x00, 7, // 0x26 '&' 0x00,0x30,0x48,0x48,0x30,0x60,0x94,0x98,0x6c,0x00,0x00, 7, // 0x27 ''' 0x00,0x20,0x20,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x28 '(' 0x00,0x04,0x08,0x10,0x10,0x10,0x10,0x08,0x04,0x00,0x00, 7, // 0x29 ')' 0x00,0x40,0x20,0x10,0x10,0x10,0x10,0x20,0x40,0x00,0x00, 7, // 0x2a '*' 0x00,0x00,0x00,0x20,0xa8,0x70,0xa8,0x20,0x00,0x00,0x00, 7, // 0x2b '+' 0x00,0x00,0x00,0x10,0x10,0x7c,0x10,0x10,0x00,0x00,0x00, 7, // 0x2c ',' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x60, 7, // 0x2d '-' 0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00, 7, // 0x2e '.' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00, 7, // 0x2f '/' 0x00,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x00,0x00, 7, // 0x30 '0' 0x00,0x38,0x44,0x4c,0x54,0x64,0x44,0x44,0x38,0x00,0x00, 7, // 0x31 '1' 0x00,0x10,0x30,0x10,0x10,0x10,0x10,0x10,0x7c,0x00,0x00, 7, // 0x32 '2' 0x00,0x38,0x44,0x04,0x08,0x10,0x20,0x44,0x7c,0x00,0x00, 7, // 0x33 '3' 0x00,0x7c,0x48,0x10,0x38,0x04,0x04,0x44,0x38,0x00,0x00, 7, // 0x34 '4' 0x00,0x08,0x10,0x20,0x48,0x48,0x7c,0x08,0x1c,0x00,0x00, 7, // 0x35 '5' 0x00,0x7c,0x40,0x40,0x78,0x04,0x04,0x44,0x38,0x00,0x00, 7, // 0x36 '6' 0x00,0x18,0x20,0x40,0x78,0x44,0x44,0x44,0x38,0x00,0x00, 7, // 0x37 '7' 0x00,0x7c,0x44,0x04,0x08,0x10,0x10,0x10,0x10,0x00,0x00, 7, // 0x38 '8' 0x00,0x38,0x44,0x44,0x38,0x44,0x44,0x44,0x38,0x00,0x00, 7, // 0x39 '9' 0x00,0x38,0x44,0x44,0x44,0x3c,0x04,0x08,0x30,0x00,0x00, 7, // 0x3a ':' 0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00, 7, // 0x3b ';' 0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x30,0x60,0x00, 7, // 0x3c '<' 0x00,0x00,0x04,0x08,0x10,0x20,0x10,0x08,0x04,0x00,0x00, 7, // 0x3d '=' 0x00,0x00,0x00,0x00,0xfc,0x00,0xfc,0x00,0x00,0x00,0x00, 7, // 0x3e '>' 0x00,0x00,0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x00,0x00, 7, // 0x3f '?' 0x00,0x70,0x88,0x88,0x10,0x20,0x20,0x00,0x20,0x00,0x00, 7, // 0x40 '@' 0x00,0x30,0x48,0x04,0x34,0x54,0x54,0x54,0x28,0x00,0x00, 7, // 0x41 'A' 0x00,0x10,0x28,0x44,0x44,0x7c,0x44,0x44,0x44,0x00,0x00, 7, // 0x42 'B' 0x00,0x78,0x44,0x44,0x78,0x44,0x44,0x44,0x78,0x00,0x00, 7, // 0x43 'C' 0x00,0x38,0x44,0x40,0x40,0x40,0x40,0x44,0x38,0x00,0x00, 7, // 0x44 'D' 0x00,0x70,0x48,0x44,0x44,0x44,0x44,0x48,0x70,0x00,0x00, 7, // 0x45 'E' 0x00,0x7c,0x40,0x40,0x70,0x40,0x40,0x40,0x7c,0x00,0x00, 7, // 0x46 'F' 0x00,0x7c,0x40,0x40,0x70,0x40,0x40,0x40,0x40,0x00,0x00, 7, // 0x47 'G' 0x00,0x38,0x44,0x40,0x40,0x5c,0x44,0x44,0x38,0x00,0x00, 7, // 0x48 'H' 0x00,0x44,0x44,0x44,0x7c,0x44,0x44,0x44,0x44,0x00,0x00, 7, // 0x49 'I' 0x00,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, 7, // 0x4a 'J' 0x00,0x1c,0x08,0x08,0x08,0x08,0x08,0x48,0x30,0x00,0x00, 7, // 0x4b 'K' 0x00,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x44,0x00,0x00, 7, // 0x4c 'L' 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7c,0x00,0x00, 7, // 0x4d 'M' 0x00,0x44,0x6c,0x54,0x54,0x44,0x44,0x44,0x44,0x00,0x00, 7, // 0x4e 'N' 0x00,0x44,0x44,0x64,0x54,0x4c,0x44,0x44,0x44,0x00,0x00, 7, // 0x4f 'O' 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, 7, // 0x50 'P' 0x00,0x78,0x44,0x44,0x44,0x78,0x40,0x40,0x40,0x00,0x00, 7, // 0x51 'Q' 0x00,0x38,0x44,0x44,0x44,0x44,0x54,0x48,0x34,0x00,0x00, 7, // 0x52 'R' 0x00,0x78,0x44,0x44,0x44,0x78,0x50,0x48,0x44,0x00,0x00, 7, // 0x53 'S' 0x00,0x38,0x44,0x40,0x38,0x04,0x44,0x44,0x38,0x00,0x00, 7, // 0x54 'T' 0x00,0x7c,0x54,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, 7, // 0x55 'U' 0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, 7, // 0x56 'V' 0x00,0x44,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x00,0x00, 7, // 0x57 'W' 0x00,0x44,0x44,0x44,0x44,0x54,0x54,0x6c,0x44,0x00,0x00, 7, // 0x58 'X' 0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x44,0x00,0x00, 7, // 0x59 'Y' 0x00,0x44,0x44,0x44,0x28,0x10,0x10,0x10,0x38,0x00,0x00, 7, // 0x5a 'Z' 0x00,0x7c,0x04,0x08,0x10,0x20,0x40,0x44,0x7c,0x00,0x00, 7, // 0x5b '[' 0x00,0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x38,0x00,0x00, 7, // 0x5c '\' 0x00,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x00,0x00, 7, // 0x5d ']' 0x00,0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x38,0x00,0x00, 7, // 0x5e '^' 0x00,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x5f '_' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00, 7, // 0x60 '`' 0x00,0x20,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x61 'a' 0x00,0x00,0x00,0x38,0x04,0x3c,0x44,0x44,0x3c,0x00,0x00, 7, // 0x62 'b' 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x78,0x00,0x00, 7, // 0x63 'c' 0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x44,0x38,0x00,0x00, 7, // 0x64 'd' 0x00,0x04,0x04,0x3c,0x44,0x44,0x44,0x44,0x3c,0x00,0x00, 7, // 0x65 'e' 0x00,0x00,0x00,0x38,0x44,0x7c,0x40,0x44,0x38,0x00,0x00, 7, // 0x66 'f' 0x00,0x18,0x24,0x20,0x70,0x20,0x20,0x20,0x70,0x00,0x00, 7, // 0x67 'g' 0x00,0x00,0x00,0x3c,0x44,0x44,0x44,0x3c,0x04,0x44,0x38, 7, // 0x68 'h' 0x00,0x40,0x40,0x40,0x58,0x64,0x44,0x44,0x44,0x00,0x00, 7, // 0x69 'i' 0x00,0x10,0x00,0x30,0x10,0x10,0x10,0x10,0x38,0x00,0x00, 7, // 0x6a 'j' 0x00,0x08,0x00,0x18,0x08,0x08,0x08,0x08,0x48,0x30,0x00, 7, // 0x6b 'k' 0x00,0x40,0x40,0x44,0x48,0x50,0x68,0x44,0x44,0x00,0x00, 7, // 0x6c 'l' 0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, 7, // 0x6d 'm' 0x00,0x00,0x00,0xa8,0x54,0x54,0x54,0x54,0x54,0x00,0x00, 7, // 0x6e 'n' 0x00,0x00,0x00,0xb8,0x44,0x44,0x44,0x44,0x44,0x00,0x00, 7, // 0x6f 'o' 0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x38,0x00,0x00, 7, // 0x70 'p' 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x40,0x40, 7, // 0x71 'q' 0x00,0x00,0x00,0x3c,0x44,0x44,0x44,0x44,0x3c,0x04,0x04, 7, // 0x72 'r' 0x00,0x00,0x00,0x58,0x64,0x44,0x40,0x40,0x40,0x00,0x00, 7, // 0x73 's' 0x00,0x00,0x00,0x3c,0x40,0x38,0x04,0x04,0x78,0x00,0x00, 7, // 0x74 't' 0x00,0x20,0x20,0x70,0x20,0x20,0x20,0x24,0x18,0x00,0x00, 7, // 0x75 'u' 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x3a,0x00,0x00, 7, // 0x76 'v' 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x28,0x10,0x00,0x00, 7, // 0x77 'w' 0x00,0x00,0x00,0x44,0x44,0x54,0x54,0x6c,0x44,0x00,0x00, 7, // 0x78 'x' 0x00,0x00,0x00,0x44,0x28,0x10,0x28,0x44,0x44,0x00,0x00, 7, // 0x79 'y' 0x00,0x00,0x00,0x44,0x44,0x44,0x3c,0x04,0x08,0x30,0x00, 7, // 0x7a 'z' 0x00,0x00,0x00,0x7c,0x08,0x10,0x20,0x44,0x7c,0x00,0x00, 7, // 0x7b '{' 0x00,0x0c,0x10,0x10,0x10,0x60,0x10,0x10,0x0c,0x00,0x00, 7, // 0x7c '|' 0x00,0x20,0x20,0x20,0x00,0x20,0x20,0x20,0x20,0x00,0x00, 7, // 0x7d '}' 0x00,0x60,0x10,0x10,0x10,0x0c,0x10,0x10,0x60,0x00,0x00, 7, // 0x7e '~' 0x00,0x00,0x64,0x98,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x7f '' 0x00,0x00,0x00,0x10,0x28,0x44,0x44,0x7c,0x00,0x00,0x00, 0 }; const int8u gse7x11_bold[] = { 11, 0, 32, 128-32, 0x00,0x00,0x0c,0x00,0x18,0x00,0x24,0x00,0x30,0x00,0x3c,0x00,0x48,0x00,0x54,0x00,0x60,0x00, 0x6c,0x00,0x78,0x00,0x84,0x00,0x90,0x00,0x9c,0x00,0xa8,0x00,0xb4,0x00,0xc0,0x00,0xcc,0x00, 0xd8,0x00,0xe4,0x00,0xf0,0x00,0xfc,0x00,0x08,0x01,0x14,0x01,0x20,0x01,0x2c,0x01,0x38,0x01, 0x44,0x01,0x50,0x01,0x5c,0x01,0x68,0x01,0x74,0x01,0x80,0x01,0x8c,0x01,0x98,0x01,0xa4,0x01, 0xb0,0x01,0xbc,0x01,0xc8,0x01,0xd4,0x01,0xe0,0x01,0xec,0x01,0xf8,0x01,0x04,0x02,0x10,0x02, 0x1c,0x02,0x28,0x02,0x34,0x02,0x40,0x02,0x4c,0x02,0x58,0x02,0x64,0x02,0x70,0x02,0x7c,0x02, 0x88,0x02,0x94,0x02,0xa0,0x02,0xac,0x02,0xb8,0x02,0xc4,0x02,0xd0,0x02,0xdc,0x02,0xe8,0x02, 0xf4,0x02,0x00,0x03,0x0c,0x03,0x18,0x03,0x24,0x03,0x30,0x03,0x3c,0x03,0x48,0x03,0x54,0x03, 0x60,0x03,0x6c,0x03,0x78,0x03,0x84,0x03,0x90,0x03,0x9c,0x03,0xa8,0x03,0xb4,0x03,0xc0,0x03, 0xcc,0x03,0xd8,0x03,0xe4,0x03,0xf0,0x03,0xfc,0x03,0x08,0x04,0x14,0x04,0x20,0x04,0x2c,0x04, 0x38,0x04,0x44,0x04,0x50,0x04,0x5c,0x04,0x68,0x04,0x74,0x04, 7, // 0x20 ' ' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x21 '!' 0x00,0x30,0x30,0x30,0x30,0x30,0x00,0x30,0x30,0x00,0x00, 7, // 0x22 '"' 0x00,0x6c,0x6c,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x23 '#' 0x00,0x48,0x48,0xfc,0x48,0x48,0xfc,0x48,0x48,0x00,0x00, 7, // 0x24 '$' 0x30,0x30,0x78,0xcc,0xc0,0x78,0x0c,0xcc,0x78,0x30,0x30, 7, // 0x25 '%' 0x00,0x00,0xc4,0x0c,0x18,0x30,0x60,0xc0,0x8c,0x00,0x00, 7, // 0x26 '&' 0x00,0x30,0x58,0x58,0x30,0x74,0xdc,0xd8,0x6c,0x00,0x00, 7, // 0x27 ''' 0x00,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x28 '(' 0x00,0x0c,0x18,0x30,0x30,0x30,0x30,0x18,0x0c,0x00,0x00, 7, // 0x29 ')' 0x00,0xc0,0x60,0x30,0x30,0x30,0x30,0x60,0xc0,0x00,0x00, 7, // 0x2a '*' 0x00,0x00,0x00,0x20,0xa8,0x70,0xa8,0x20,0x00,0x00,0x00, 7, // 0x2b '+' 0x00,0x00,0x00,0x30,0x30,0xfc,0x30,0x30,0x00,0x00,0x00, 7, // 0x2c ',' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x60,0x00, 7, // 0x2d '-' 0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00, 7, // 0x2e '.' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00, 7, // 0x2f '/' 0x00,0x0c,0x0c,0x18,0x18,0x30,0x30,0x60,0x60,0x00,0x00, 7, // 0x30 '0' 0x00,0x78,0xcc,0xcc,0xdc,0xec,0xcc,0xcc,0x78,0x00,0x00, 7, // 0x31 '1' 0x00,0x30,0x70,0xf0,0x30,0x30,0x30,0x30,0xfc,0x00,0x00, 7, // 0x32 '2' 0x00,0x78,0xcc,0xcc,0x18,0x30,0x60,0xcc,0xfc,0x00,0x00, 7, // 0x33 '3' 0x00,0xfc,0x98,0x30,0x78,0x0c,0x0c,0xcc,0x78,0x00,0x00, 7, // 0x34 '4' 0x00,0x18,0x30,0x68,0xd8,0xd8,0xfc,0x18,0x3c,0x00,0x00, 7, // 0x35 '5' 0x00,0xfc,0xc0,0xc0,0xf8,0x0c,0x0c,0xcc,0x78,0x00,0x00, 7, // 0x36 '6' 0x00,0x38,0x60,0xc0,0xf8,0xcc,0xcc,0xcc,0x78,0x00,0x00, 7, // 0x37 '7' 0x00,0xfc,0x8c,0x0c,0x18,0x30,0x30,0x30,0x30,0x00,0x00, 7, // 0x38 '8' 0x00,0x78,0xcc,0xcc,0x78,0xcc,0xcc,0xcc,0x78,0x00,0x00, 7, // 0x39 '9' 0x00,0x78,0xcc,0xcc,0xcc,0x7c,0x0c,0x18,0x70,0x00,0x00, 7, // 0x3a ':' 0x00,0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x00,0x00,0x00, 7, // 0x3b ';' 0x00,0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x30,0x60,0x00, 7, // 0x3c '<' 0x00,0x00,0x0c,0x18,0x30,0x60,0x30,0x18,0x0c,0x00,0x00, 7, // 0x3d '=' 0x00,0x00,0x00,0x00,0xfc,0x00,0xfc,0x00,0x00,0x00,0x00, 7, // 0x3e '>' 0x00,0x00,0x60,0x30,0x18,0x0c,0x18,0x30,0x60,0x00,0x00, 7, // 0x3f '?' 0x00,0x78,0xcc,0xcc,0x18,0x30,0x30,0x00,0x30,0x00,0x00, 7, // 0x40 '@' 0x00,0x70,0x88,0x04,0x74,0xb4,0xb4,0xb4,0x68,0x00,0x00, 7, // 0x41 'A' 0x00,0x30,0x78,0xcc,0xcc,0xfc,0xcc,0xcc,0xcc,0x00,0x00, 7, // 0x42 'B' 0x00,0xf8,0xcc,0xcc,0xf8,0xcc,0xcc,0xcc,0xf8,0x00,0x00, 7, // 0x43 'C' 0x00,0x78,0xcc,0xc0,0xc0,0xc0,0xc0,0xcc,0x78,0x00,0x00, 7, // 0x44 'D' 0x00,0xf0,0xd8,0xcc,0xcc,0xcc,0xcc,0xd8,0xf0,0x00,0x00, 7, // 0x45 'E' 0x00,0xfc,0xc4,0xd0,0xf0,0xd0,0xc0,0xc4,0xfc,0x00,0x00, 7, // 0x46 'F' 0x00,0xfc,0xc4,0xd0,0xf0,0xd0,0xc0,0xc0,0xc0,0x00,0x00, 7, // 0x47 'G' 0x00,0x78,0xcc,0xc0,0xc0,0xdc,0xcc,0xcc,0x78,0x00,0x00, 7, // 0x48 'H' 0x00,0xcc,0xcc,0xcc,0xfc,0xcc,0xcc,0xcc,0xcc,0x00,0x00, 7, // 0x49 'I' 0x00,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00, 7, // 0x4a 'J' 0x00,0x3c,0x18,0x18,0x18,0x18,0xd8,0xd8,0x70,0x00,0x00, 7, // 0x4b 'K' 0x00,0xcc,0xcc,0xd8,0xf0,0xd8,0xcc,0xcc,0xcc,0x00,0x00, 7, // 0x4c 'L' 0x00,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc4,0xfc,0x00,0x00, 7, // 0x4d 'M' 0x00,0x84,0xcc,0xfc,0xb4,0xcc,0xcc,0xcc,0xcc,0x00,0x00, 7, // 0x4e 'N' 0x00,0xcc,0xcc,0xec,0xfc,0xdc,0xcc,0xcc,0xcc,0x00,0x00, 7, // 0x4f 'O' 0x00,0x78,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00, 7, // 0x50 'P' 0x00,0xf8,0xcc,0xcc,0xcc,0xf8,0xc0,0xc0,0xc0,0x00,0x00, 7, // 0x51 'Q' 0x00,0x78,0xcc,0xcc,0xcc,0xcc,0xdc,0x78,0x18,0x0c,0x00, 7, // 0x52 'R' 0x00,0xf8,0xcc,0xcc,0xcc,0xf8,0xd8,0xcc,0xcc,0x00,0x00, 7, // 0x53 'S' 0x00,0x78,0xcc,0xe0,0x70,0x38,0x1c,0xcc,0x78,0x00,0x00, 7, // 0x54 'T' 0x00,0xfc,0xb4,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00, 7, // 0x55 'U' 0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00, 7, // 0x56 'V' 0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x78,0x30,0x00,0x00, 7, // 0x57 'W' 0x00,0xcc,0xcc,0xcc,0xcc,0xb4,0xfc,0xcc,0x84,0x00,0x00, 7, // 0x58 'X' 0x00,0xcc,0xcc,0x78,0x30,0x78,0xcc,0xcc,0xcc,0x00,0x00, 7, // 0x59 'Y' 0x00,0xcc,0xcc,0xcc,0x78,0x30,0x30,0x30,0x78,0x00,0x00, 7, // 0x5a 'Z' 0x00,0xfc,0x8c,0x18,0x30,0x60,0xc0,0xc4,0xfc,0x00,0x00, 7, // 0x5b '[' 0x00,0x78,0x60,0x60,0x60,0x60,0x60,0x60,0x78,0x00,0x00, 7, // 0x5c '\' 0x00,0x60,0x60,0x30,0x30,0x18,0x18,0x0c,0x0c,0x00,0x00, 7, // 0x5d ']' 0x00,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x78,0x00,0x00, 7, // 0x5e '^' 0x00,0x10,0x38,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x5f '_' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00, 7, // 0x60 '`' 0x00,0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x61 'a' 0x00,0x00,0x00,0x70,0x18,0x78,0xd8,0xd8,0x6c,0x00,0x00, 7, // 0x62 'b' 0x00,0x60,0x60,0x60,0x78,0x6c,0x6c,0x6c,0x78,0x00,0x00, 7, // 0x63 'c' 0x00,0x00,0x00,0x78,0xcc,0xc0,0xc0,0xcc,0x78,0x00,0x00, 7, // 0x64 'd' 0x00,0x18,0x18,0x18,0x78,0xd8,0xd8,0xd8,0x6c,0x00,0x00, 7, // 0x65 'e' 0x00,0x00,0x00,0x78,0xcc,0xfc,0xc0,0xcc,0x78,0x00,0x00, 7, // 0x66 'f' 0x00,0x18,0x34,0x30,0x78,0x30,0x30,0x30,0x78,0x00,0x00, 7, // 0x67 'g' 0x00,0x00,0x00,0x6c,0xd8,0xd8,0xd8,0x78,0x18,0xd8,0x70, 7, // 0x68 'h' 0x00,0xc0,0xc0,0xd8,0xec,0xcc,0xcc,0xcc,0xcc,0x00,0x00, 7, // 0x69 'i' 0x00,0x30,0x00,0x70,0x30,0x30,0x30,0x30,0x78,0x00,0x00, 7, // 0x6a 'j' 0x00,0x0c,0x00,0x1c,0x0c,0x0c,0x0c,0x0c,0x6c,0x6c,0x38, 7, // 0x6b 'k' 0x00,0xc0,0xc0,0xcc,0xcc,0xd8,0xf0,0xd8,0xcc,0x00,0x00, 7, // 0x6c 'l' 0x00,0x70,0x30,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00, 7, // 0x6d 'm' 0x00,0x00,0x00,0xe8,0xfc,0xd4,0xd4,0xc4,0xc4,0x00,0x00, 7, // 0x6e 'n' 0x00,0x00,0x00,0xd8,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,0x00, 7, // 0x6f 'o' 0x00,0x00,0x00,0x78,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00, 7, // 0x70 'p' 0x00,0x00,0x00,0xf8,0xcc,0xcc,0xcc,0xf8,0xc0,0xc0,0xc0, 7, // 0x71 'q' 0x00,0x00,0x00,0x7c,0xcc,0xcc,0xcc,0x7c,0x0c,0x0c,0x0c, 7, // 0x72 'r' 0x00,0x00,0x00,0xd8,0xec,0xcc,0xc0,0xc0,0xc0,0x00,0x00, 7, // 0x73 's' 0x00,0x00,0x00,0x78,0xcc,0x60,0x18,0xcc,0x78,0x00,0x00, 7, // 0x74 't' 0x00,0x20,0x60,0x60,0xf0,0x60,0x60,0x68,0x30,0x00,0x00, 7, // 0x75 'u' 0x00,0x00,0x00,0xd8,0xd8,0xd8,0xd8,0xd8,0x6c,0x00,0x00, 7, // 0x76 'v' 0x00,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0x78,0x30,0x00,0x00, 7, // 0x77 'w' 0x00,0x00,0x00,0xcc,0xcc,0xb4,0xfc,0xcc,0x84,0x00,0x00, 7, // 0x78 'x' 0x00,0x00,0x00,0xcc,0x78,0x30,0x78,0xcc,0xcc,0x00,0x00, 7, // 0x79 'y' 0x00,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0x18,0xf0, 7, // 0x7a 'z' 0x00,0x00,0x00,0xfc,0x98,0x30,0x60,0xc4,0xfc,0x00,0x00, 7, // 0x7b '{' 0x1c,0x30,0x30,0x30,0xe0,0x30,0x30,0x30,0x1c,0x00,0x00, 7, // 0x7c '|' 0x30,0x30,0x30,0x30,0x00,0x30,0x30,0x30,0x30,0x00,0x00, 7, // 0x7d '}' 0xe0,0x30,0x30,0x30,0x1c,0x30,0x30,0x30,0xe0,0x00,0x00, 7, // 0x7e '~' 0x00,0x34,0x58,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x7f '' 0x00,0x00,0x00,0x30,0x78,0xcc,0xcc,0xfc,0x00,0x00,0x00, 0 }; const int8u gse7x15[] = { 15, 0, 32, 128-32, 0x00,0x00,0x10,0x00,0x20,0x00,0x30,0x00,0x40,0x00,0x50,0x00,0x60,0x00,0x70,0x00,0x80,0x00, 0x90,0x00,0xa0,0x00,0xb0,0x00,0xc0,0x00,0xd0,0x00,0xe0,0x00,0xf0,0x00,0x00,0x01,0x10,0x01, 0x20,0x01,0x30,0x01,0x40,0x01,0x50,0x01,0x60,0x01,0x70,0x01,0x80,0x01,0x90,0x01,0xa0,0x01, 0xb0,0x01,0xc0,0x01,0xd0,0x01,0xe0,0x01,0xf0,0x01,0x00,0x02,0x10,0x02,0x20,0x02,0x30,0x02, 0x40,0x02,0x50,0x02,0x60,0x02,0x70,0x02,0x80,0x02,0x90,0x02,0xa0,0x02,0xb0,0x02,0xc0,0x02, 0xd0,0x02,0xe0,0x02,0xf0,0x02,0x00,0x03,0x10,0x03,0x20,0x03,0x30,0x03,0x40,0x03,0x50,0x03, 0x60,0x03,0x70,0x03,0x80,0x03,0x90,0x03,0xa0,0x03,0xb0,0x03,0xc0,0x03,0xd0,0x03,0xe0,0x03, 0xf0,0x03,0x00,0x04,0x10,0x04,0x20,0x04,0x30,0x04,0x40,0x04,0x50,0x04,0x60,0x04,0x70,0x04, 0x80,0x04,0x90,0x04,0xa0,0x04,0xb0,0x04,0xc0,0x04,0xd0,0x04,0xe0,0x04,0xf0,0x04,0x00,0x05, 0x10,0x05,0x20,0x05,0x30,0x05,0x40,0x05,0x50,0x05,0x60,0x05,0x70,0x05,0x80,0x05,0x90,0x05, 0xa0,0x05,0xb0,0x05,0xc0,0x05,0xd0,0x05,0xe0,0x05,0xf0,0x05, 7, // 0x20 ' ' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x21 '!' 0x00,0x00,0x10,0x38,0x38,0x38,0x38,0x10,0x10,0x00,0x10,0x10,0x00,0x00,0x00, 7, // 0x22 '"' 0x00,0x00,0x24,0x24,0x24,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x23 '#' 0x00,0x00,0x48,0x48,0x48,0xfc,0x48,0x48,0xfc,0x48,0x48,0x48,0x00,0x00,0x00, 7, // 0x24 '$' 0x00,0x00,0x10,0x38,0x54,0x50,0x38,0x14,0x54,0x54,0x38,0x10,0x00,0x00,0x00, 7, // 0x25 '%' 0x00,0x00,0x44,0x44,0x08,0x08,0x10,0x10,0x20,0x20,0x44,0x44,0x00,0x00,0x00, 7, // 0x26 '&' 0x00,0x00,0x00,0x30,0x48,0x48,0x30,0x60,0x94,0x98,0x90,0x6c,0x00,0x00,0x00, 7, // 0x27 ''' 0x00,0x00,0x20,0x20,0x20,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x28 '(' 0x00,0x04,0x08,0x10,0x20,0x20,0x20,0x20,0x20,0x10,0x08,0x04,0x00,0x00,0x00, 7, // 0x29 ')' 0x00,0x40,0x20,0x10,0x08,0x08,0x08,0x08,0x08,0x10,0x20,0x40,0x00,0x00,0x00, 7, // 0x2a '*' 0x00,0x00,0x00,0x00,0x00,0x20,0xa8,0x70,0xa8,0x20,0x00,0x00,0x00,0x00,0x00, 7, // 0x2b '+' 0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x7c,0x10,0x10,0x10,0x00,0x00,0x00,0x00, 7, // 0x2c ',' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x60,0x00, 7, // 0x2d '-' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x2e '.' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00, 7, // 0x2f '/' 0x00,0x00,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x00,0x00,0x00, 7, // 0x30 '0' 0x00,0x00,0x38,0x44,0x44,0x4c,0x54,0x64,0x44,0x44,0x44,0x38,0x00,0x00,0x00, 7, // 0x31 '1' 0x00,0x00,0x10,0x10,0x30,0x10,0x10,0x10,0x10,0x10,0x10,0x7c,0x00,0x00,0x00, 7, // 0x32 '2' 0x00,0x00,0x38,0x44,0x44,0x04,0x08,0x10,0x20,0x40,0x44,0x7c,0x00,0x00,0x00, 7, // 0x33 '3' 0x00,0x00,0x7c,0x44,0x08,0x10,0x38,0x04,0x04,0x04,0x44,0x38,0x00,0x00,0x00, 7, // 0x34 '4' 0x00,0x00,0x08,0x10,0x20,0x40,0x48,0x48,0x7c,0x08,0x08,0x1c,0x00,0x00,0x00, 7, // 0x35 '5' 0x00,0x00,0x7c,0x40,0x40,0x40,0x78,0x04,0x04,0x04,0x44,0x38,0x00,0x00,0x00, 7, // 0x36 '6' 0x00,0x00,0x18,0x20,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, 7, // 0x37 '7' 0x00,0x00,0x7c,0x44,0x04,0x04,0x08,0x08,0x10,0x10,0x10,0x10,0x00,0x00,0x00, 7, // 0x38 '8' 0x00,0x00,0x38,0x44,0x44,0x44,0x38,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, 7, // 0x39 '9' 0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x3c,0x04,0x04,0x08,0x30,0x00,0x00,0x00, 7, // 0x3a ':' 0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00, 7, // 0x3b ';' 0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x30,0x30,0x60,0x00,0x00, 7, // 0x3c '<' 0x00,0x00,0x00,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x00,0x00,0x00, 7, // 0x3d '=' 0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x3e '>' 0x00,0x00,0x00,0x40,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x40,0x00,0x00,0x00, 7, // 0x3f '?' 0x00,0x00,0x78,0x84,0x84,0x84,0x08,0x10,0x20,0x20,0x00,0x20,0x00,0x00,0x00, 7, // 0x40 '@' 0x00,0x00,0x00,0x30,0x48,0x04,0x34,0x54,0x54,0x54,0x54,0x28,0x00,0x00,0x00, 7, // 0x41 'A' 0x00,0x00,0x10,0x28,0x44,0x44,0x44,0x7c,0x44,0x44,0x44,0x44,0x00,0x00,0x00, 7, // 0x42 'B' 0x00,0x00,0x78,0x44,0x44,0x44,0x78,0x44,0x44,0x44,0x44,0x78,0x00,0x00,0x00, 7, // 0x43 'C' 0x00,0x00,0x38,0x44,0x44,0x40,0x40,0x40,0x40,0x44,0x44,0x38,0x00,0x00,0x00, 7, // 0x44 'D' 0x00,0x00,0x70,0x48,0x44,0x44,0x44,0x44,0x44,0x44,0x48,0x70,0x00,0x00,0x00, 7, // 0x45 'E' 0x00,0x00,0x7c,0x40,0x40,0x40,0x70,0x40,0x40,0x40,0x40,0x7c,0x00,0x00,0x00, 7, // 0x46 'F' 0x00,0x00,0x7c,0x40,0x40,0x40,0x70,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, 7, // 0x47 'G' 0x00,0x00,0x38,0x44,0x40,0x40,0x40,0x5c,0x44,0x44,0x44,0x38,0x00,0x00,0x00, 7, // 0x48 'H' 0x00,0x00,0x44,0x44,0x44,0x44,0x7c,0x44,0x44,0x44,0x44,0x44,0x00,0x00,0x00, 7, // 0x49 'I' 0x00,0x00,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00, 7, // 0x4a 'J' 0x00,0x00,0x1c,0x08,0x08,0x08,0x08,0x08,0x08,0x48,0x48,0x30,0x00,0x00,0x00, 7, // 0x4b 'K' 0x00,0x00,0x44,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x44,0x44,0x00,0x00,0x00, 7, // 0x4c 'L' 0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7c,0x00,0x00,0x00, 7, // 0x4d 'M' 0x00,0x00,0x44,0x6c,0x54,0x54,0x44,0x44,0x44,0x44,0x44,0x44,0x00,0x00,0x00, 7, // 0x4e 'N' 0x00,0x00,0x44,0x44,0x44,0x64,0x54,0x4c,0x44,0x44,0x44,0x44,0x00,0x00,0x00, 7, // 0x4f 'O' 0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, 7, // 0x50 'P' 0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x40,0x40,0x40,0x40,0x00,0x00,0x00, 7, // 0x51 'Q' 0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x54,0x48,0x34,0x00,0x00,0x00, 7, // 0x52 'R' 0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x50,0x48,0x44,0x44,0x00,0x00,0x00, 7, // 0x53 'S' 0x00,0x00,0x38,0x44,0x44,0x40,0x38,0x04,0x04,0x44,0x44,0x38,0x00,0x00,0x00, 7, // 0x54 'T' 0x00,0x00,0x7c,0x54,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00, 7, // 0x55 'U' 0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, 7, // 0x56 'V' 0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x00,0x00,0x00, 7, // 0x57 'W' 0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x54,0x54,0x6c,0x44,0x00,0x00,0x00, 7, // 0x58 'X' 0x00,0x00,0x44,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x44,0x44,0x00,0x00,0x00, 7, // 0x59 'Y' 0x00,0x00,0x44,0x44,0x44,0x44,0x28,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00, 7, // 0x5a 'Z' 0x00,0x00,0x7c,0x04,0x04,0x08,0x10,0x20,0x40,0x40,0x40,0x7c,0x00,0x00,0x00, 7, // 0x5b '[' 0x00,0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x38,0x00,0x00, 7, // 0x5c '\' 0x00,0x00,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x00,0x00,0x00, 7, // 0x5d ']' 0x00,0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x38,0x00,0x00, 7, // 0x5e '^' 0x00,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x5f '_' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00, 7, // 0x60 '`' 0x00,0x20,0x20,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x61 'a' 0x00,0x00,0x00,0x00,0x38,0x44,0x04,0x3c,0x44,0x44,0x44,0x3a,0x00,0x00,0x00, 7, // 0x62 'b' 0x00,0x00,0x40,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x78,0x00,0x00,0x00, 7, // 0x63 'c' 0x00,0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x40,0x40,0x44,0x38,0x00,0x00,0x00, 7, // 0x64 'd' 0x00,0x00,0x04,0x04,0x04,0x3c,0x44,0x44,0x44,0x44,0x44,0x3a,0x00,0x00,0x00, 7, // 0x65 'e' 0x00,0x00,0x00,0x00,0x38,0x44,0x44,0x7c,0x40,0x40,0x44,0x38,0x00,0x00,0x00, 7, // 0x66 'f' 0x00,0x00,0x18,0x24,0x20,0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00,0x00, 7, // 0x67 'g' 0x00,0x00,0x00,0x00,0x3a,0x44,0x44,0x44,0x44,0x44,0x3c,0x04,0x44,0x38,0x00, 7, // 0x68 'h' 0x00,0x00,0x40,0x40,0x40,0x58,0x64,0x44,0x44,0x44,0x44,0x44,0x00,0x00,0x00, 7, // 0x69 'i' 0x00,0x00,0x10,0x10,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00, 7, // 0x6a 'j' 0x00,0x00,0x08,0x08,0x00,0x18,0x08,0x08,0x08,0x08,0x08,0x48,0x48,0x30,0x00, 7, // 0x6b 'k' 0x00,0x00,0x40,0x40,0x44,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x00,0x00,0x00, 7, // 0x6c 'l' 0x00,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00, 7, // 0x6d 'm' 0x00,0x00,0x00,0x00,0xa8,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x00,0x00,0x00, 7, // 0x6e 'n' 0x00,0x00,0x00,0x00,0xb8,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x00,0x00,0x00, 7, // 0x6f 'o' 0x00,0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, 7, // 0x70 'p' 0x00,0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x44,0x78,0x40,0x40,0x40,0x00, 7, // 0x71 'q' 0x00,0x00,0x00,0x00,0x3c,0x44,0x44,0x44,0x44,0x44,0x3c,0x04,0x04,0x04,0x00, 7, // 0x72 'r' 0x00,0x00,0x00,0x00,0x58,0x64,0x44,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, 7, // 0x73 's' 0x00,0x00,0x00,0x00,0x38,0x44,0x40,0x38,0x04,0x44,0x44,0x38,0x00,0x00,0x00, 7, // 0x74 't' 0x00,0x00,0x20,0x20,0x20,0x70,0x20,0x20,0x20,0x20,0x24,0x18,0x00,0x00,0x00, 7, // 0x75 'u' 0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x3a,0x00,0x00,0x00, 7, // 0x76 'v' 0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x00,0x00,0x00, 7, // 0x77 'w' 0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x54,0x54,0x6c,0x44,0x00,0x00,0x00, 7, // 0x78 'x' 0x00,0x00,0x00,0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x44,0x00,0x00,0x00, 7, // 0x79 'y' 0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x3c,0x04,0x08,0x70,0x00, 7, // 0x7a 'z' 0x00,0x00,0x00,0x00,0x7c,0x04,0x08,0x10,0x20,0x40,0x40,0x7c,0x00,0x00,0x00, 7, // 0x7b '{' 0x00,0x0c,0x10,0x10,0x10,0x10,0x10,0x60,0x10,0x10,0x10,0x10,0x0c,0x00,0x00, 7, // 0x7c '|' 0x00,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x00,0x00, 7, // 0x7d '}' 0x00,0x60,0x10,0x10,0x10,0x10,0x10,0x0c,0x10,0x10,0x10,0x10,0x60,0x00,0x00, 7, // 0x7e '~' 0x00,0x00,0x64,0x98,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x7f '' 0x00,0x00,0x00,0x00,0x00,0x10,0x28,0x44,0x44,0x7c,0x00,0x00,0x00,0x00,0x00, 0 }; const int8u gse7x15_bold[] = { 15, 0, 32, 128-32, 0x00,0x00,0x10,0x00,0x20,0x00,0x30,0x00,0x40,0x00,0x50,0x00,0x60,0x00,0x70,0x00,0x80,0x00, 0x90,0x00,0xa0,0x00,0xb0,0x00,0xc0,0x00,0xd0,0x00,0xe0,0x00,0xf0,0x00,0x00,0x01,0x10,0x01, 0x20,0x01,0x30,0x01,0x40,0x01,0x50,0x01,0x60,0x01,0x70,0x01,0x80,0x01,0x90,0x01,0xa0,0x01, 0xb0,0x01,0xc0,0x01,0xd0,0x01,0xe0,0x01,0xf0,0x01,0x00,0x02,0x10,0x02,0x20,0x02,0x30,0x02, 0x40,0x02,0x50,0x02,0x60,0x02,0x70,0x02,0x80,0x02,0x90,0x02,0xa0,0x02,0xb0,0x02,0xc0,0x02, 0xd0,0x02,0xe0,0x02,0xf0,0x02,0x00,0x03,0x10,0x03,0x20,0x03,0x30,0x03,0x40,0x03,0x50,0x03, 0x60,0x03,0x70,0x03,0x80,0x03,0x90,0x03,0xa0,0x03,0xb0,0x03,0xc0,0x03,0xd0,0x03,0xe0,0x03, 0xf0,0x03,0x00,0x04,0x10,0x04,0x20,0x04,0x30,0x04,0x40,0x04,0x50,0x04,0x60,0x04,0x70,0x04, 0x80,0x04,0x90,0x04,0xa0,0x04,0xb0,0x04,0xc0,0x04,0xd0,0x04,0xe0,0x04,0xf0,0x04,0x00,0x05, 0x10,0x05,0x20,0x05,0x30,0x05,0x40,0x05,0x50,0x05,0x60,0x05,0x70,0x05,0x80,0x05,0x90,0x05, 0xa0,0x05,0xb0,0x05,0xc0,0x05,0xd0,0x05,0xe0,0x05,0xf0,0x05, 7, // 0x20 ' ' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x21 '!' 0x00,0x00,0x00,0x30,0x78,0x78,0x78,0x30,0x30,0x00,0x30,0x30,0x00,0x00,0x00, 7, // 0x22 '"' 0x00,0x00,0x6c,0x6c,0x6c,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x23 '#' 0x00,0x00,0x48,0x48,0x48,0xfc,0x48,0x48,0xfc,0x48,0x48,0x48,0x00,0x00,0x00, 7, // 0x24 '$' 0x00,0x30,0x30,0x78,0xcc,0xe0,0x70,0x38,0x1c,0xcc,0x78,0x30,0x30,0x00,0x00, 7, // 0x25 '%' 0x00,0x00,0x00,0x64,0x6c,0x08,0x18,0x10,0x30,0x20,0x6c,0x4c,0x00,0x00,0x00, 7, // 0x26 '&' 0x00,0x00,0x00,0x30,0x58,0x58,0x30,0x74,0xdc,0xd8,0xd8,0x6c,0x00,0x00,0x00, 7, // 0x27 ''' 0x00,0x00,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x28 '(' 0x00,0x0c,0x18,0x30,0x60,0x60,0x60,0x60,0x60,0x30,0x18,0x0c,0x00,0x00,0x00, 7, // 0x29 ')' 0x00,0xc0,0x60,0x30,0x18,0x18,0x18,0x18,0x18,0x30,0x60,0xc0,0x00,0x00,0x00, 7, // 0x2a '*' 0x00,0x00,0x00,0x00,0x00,0x20,0xa8,0x70,0xa8,0x20,0x00,0x00,0x00,0x00,0x00, 7, // 0x2b '+' 0x00,0x00,0x00,0x00,0x00,0x30,0x30,0xfc,0x30,0x30,0x00,0x00,0x00,0x00,0x00, 7, // 0x2c ',' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x60,0x00, 7, // 0x2d '-' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x2e '.' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00, 7, // 0x2f '/' 0x00,0x00,0x0c,0x0c,0x18,0x18,0x30,0x30,0x60,0x60,0xc0,0xc0,0x00,0x00,0x00, 7, // 0x30 '0' 0x00,0x00,0x78,0xcc,0xcc,0xcc,0xdc,0xec,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00, 7, // 0x31 '1' 0x00,0x00,0x30,0x30,0x70,0xf0,0x30,0x30,0x30,0x30,0x30,0xfc,0x00,0x00,0x00, 7, // 0x32 '2' 0x00,0x00,0x78,0xcc,0xcc,0x0c,0x18,0x30,0x60,0xc0,0xcc,0xfc,0x00,0x00,0x00, 7, // 0x33 '3' 0x00,0x00,0xfc,0x8c,0x18,0x30,0x78,0x0c,0x0c,0x0c,0xcc,0x78,0x00,0x00,0x00, 7, // 0x34 '4' 0x00,0x00,0x18,0x30,0x60,0xc8,0xd8,0xd8,0xfc,0x18,0x18,0x3c,0x00,0x00,0x00, 7, // 0x35 '5' 0x00,0x00,0xfc,0xc0,0xc0,0xc0,0xf8,0x0c,0x0c,0x0c,0xcc,0x78,0x00,0x00,0x00, 7, // 0x36 '6' 0x00,0x00,0x38,0x60,0xc0,0xc0,0xf8,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00, 7, // 0x37 '7' 0x00,0x00,0xfc,0x8c,0x0c,0x0c,0x18,0x18,0x30,0x30,0x30,0x30,0x00,0x00,0x00, 7, // 0x38 '8' 0x00,0x00,0x78,0xcc,0xcc,0xcc,0x78,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00, 7, // 0x39 '9' 0x00,0x00,0x78,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0x0c,0x18,0x70,0x00,0x00,0x00, 7, // 0x3a ':' 0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00, 7, // 0x3b ';' 0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x60,0x00, 7, // 0x3c '<' 0x00,0x00,0x00,0x0c,0x18,0x30,0x60,0xc0,0x60,0x30,0x18,0x0c,0x00,0x00,0x00, 7, // 0x3d '=' 0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x3e '>' 0x00,0x00,0x00,0xc0,0x60,0x30,0x18,0x0c,0x18,0x30,0x60,0xc0,0x00,0x00,0x00, 7, // 0x3f '?' 0x00,0x00,0x78,0xcc,0xcc,0x18,0x30,0x30,0x30,0x00,0x30,0x30,0x00,0x00,0x00, 7, // 0x40 '@' 0x00,0x00,0x00,0x70,0x88,0x04,0x74,0xb4,0xb4,0xb4,0xb4,0x68,0x00,0x00,0x00, 7, // 0x41 'A' 0x00,0x00,0x30,0x78,0xcc,0xcc,0xcc,0xfc,0xcc,0xcc,0xcc,0xcc,0x00,0x00,0x00, 7, // 0x42 'B' 0x00,0x00,0xf8,0xcc,0xcc,0xcc,0xf8,0xcc,0xcc,0xcc,0xcc,0xf8,0x00,0x00,0x00, 7, // 0x43 'C' 0x00,0x00,0x78,0xcc,0xc4,0xc0,0xc0,0xc0,0xc0,0xc4,0xcc,0x78,0x00,0x00,0x00, 7, // 0x44 'D' 0x00,0x00,0xf0,0xd8,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xd8,0xf0,0x00,0x00,0x00, 7, // 0x45 'E' 0x00,0x00,0xfc,0xc4,0xc0,0xd0,0xf0,0xd0,0xc0,0xc0,0xc4,0xfc,0x00,0x00,0x00, 7, // 0x46 'F' 0x00,0x00,0xfc,0xc4,0xc0,0xd0,0xf0,0xd0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00, 7, // 0x47 'G' 0x00,0x00,0x78,0xcc,0xc0,0xc0,0xc0,0xdc,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00, 7, // 0x48 'H' 0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xfc,0xcc,0xcc,0xcc,0xcc,0xcc,0x00,0x00,0x00, 7, // 0x49 'I' 0x00,0x00,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00, 7, // 0x4a 'J' 0x00,0x00,0x3c,0x18,0x18,0x18,0x18,0x18,0x18,0xd8,0xd8,0x70,0x00,0x00,0x00, 7, // 0x4b 'K' 0x00,0x00,0xcc,0xcc,0xd8,0xd8,0xf0,0xd8,0xd8,0xcc,0xcc,0xcc,0x00,0x00,0x00, 7, // 0x4c 'L' 0x00,0x00,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc4,0xfc,0x00,0x00,0x00, 7, // 0x4d 'M' 0x00,0x00,0x84,0xcc,0xfc,0xb4,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x00,0x00,0x00, 7, // 0x4e 'N' 0x00,0x00,0xcc,0xcc,0xcc,0xec,0xfc,0xdc,0xcc,0xcc,0xcc,0xcc,0x00,0x00,0x00, 7, // 0x4f 'O' 0x00,0x00,0x78,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00, 7, // 0x50 'P' 0x00,0x00,0xf8,0xcc,0xcc,0xcc,0xcc,0xf8,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00, 7, // 0x51 'Q' 0x00,0x00,0x78,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xdc,0x78,0x18,0x0c,0x00,0x00, 7, // 0x52 'R' 0x00,0x00,0xf8,0xcc,0xcc,0xcc,0xcc,0xf8,0xd8,0xcc,0xcc,0xcc,0x00,0x00,0x00, 7, // 0x53 'S' 0x00,0x00,0x78,0xcc,0xcc,0xe0,0x70,0x38,0x1c,0xcc,0xcc,0x78,0x00,0x00,0x00, 7, // 0x54 'T' 0x00,0x00,0xfc,0xb4,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x00, 7, // 0x55 'U' 0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00, 7, // 0x56 'V' 0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x78,0x30,0x00,0x00,0x00, 7, // 0x57 'W' 0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xb4,0xfc,0xcc,0x84,0x00,0x00,0x00, 7, // 0x58 'X' 0x00,0x00,0xcc,0xcc,0xcc,0x78,0x30,0x78,0xcc,0xcc,0xcc,0xcc,0x00,0x00,0x00, 7, // 0x59 'Y' 0x00,0x00,0xcc,0xcc,0xcc,0xcc,0x78,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00, 7, // 0x5a 'Z' 0x00,0x00,0xfc,0x8c,0x0c,0x18,0x30,0x60,0xc0,0xc0,0xc4,0xfc,0x00,0x00,0x00, 7, // 0x5b '[' 0x00,0x78,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x78,0x00,0x00, 7, // 0x5c '\' 0x00,0x00,0xc0,0xc0,0x60,0x60,0x30,0x30,0x18,0x18,0x0c,0x0c,0x00,0x00,0x00, 7, // 0x5d ']' 0x00,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x78,0x00,0x00, 7, // 0x5e '^' 0x00,0x10,0x38,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x5f '_' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00, 7, // 0x60 '`' 0x00,0x30,0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x61 'a' 0x00,0x00,0x00,0x00,0x70,0xd8,0x18,0x78,0xd8,0xd8,0xd8,0x6c,0x00,0x00,0x00, 7, // 0x62 'b' 0x00,0x00,0x60,0x60,0x60,0x78,0x6c,0x6c,0x6c,0x6c,0x6c,0x78,0x00,0x00,0x00, 7, // 0x63 'c' 0x00,0x00,0x00,0x00,0x78,0xcc,0xc0,0xc0,0xc0,0xc0,0xcc,0x78,0x00,0x00,0x00, 7, // 0x64 'd' 0x00,0x00,0x18,0x18,0x18,0x78,0xd8,0xd8,0xd8,0xd8,0xd8,0x6c,0x00,0x00,0x00, 7, // 0x65 'e' 0x00,0x00,0x00,0x00,0x78,0xcc,0xcc,0xfc,0xc0,0xc0,0xcc,0x78,0x00,0x00,0x00, 7, // 0x66 'f' 0x00,0x00,0x30,0x68,0x60,0x60,0xf0,0x60,0x60,0x60,0x60,0xf0,0x00,0x00,0x00, 7, // 0x67 'g' 0x00,0x00,0x00,0x00,0x6c,0xd8,0xd8,0xd8,0xd8,0xd8,0x78,0x18,0xd8,0x70,0x00, 7, // 0x68 'h' 0x00,0x00,0xc0,0xc0,0xc0,0xd8,0xec,0xcc,0xcc,0xcc,0xcc,0xcc,0x00,0x00,0x00, 7, // 0x69 'i' 0x00,0x00,0x30,0x30,0x00,0x70,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00, 7, // 0x6a 'j' 0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0xd8,0xd8,0x70,0x00, 7, // 0x6b 'k' 0x00,0x00,0xc0,0xc0,0xcc,0xcc,0xcc,0xd8,0xf0,0xd8,0xcc,0xcc,0x00,0x00,0x00, 7, // 0x6c 'l' 0x00,0x00,0x70,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00, 7, // 0x6d 'm' 0x00,0x00,0x00,0x00,0xe8,0xfc,0xd4,0xd4,0xd4,0xc4,0xc4,0xc4,0x00,0x00,0x00, 7, // 0x6e 'n' 0x00,0x00,0x00,0x00,0xd8,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,0x00,0x00, 7, // 0x6f 'o' 0x00,0x00,0x00,0x00,0x78,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00, 7, // 0x70 'p' 0x00,0x00,0x00,0x00,0xf8,0xcc,0xcc,0xcc,0xcc,0xcc,0xf8,0xc0,0xc0,0xc0,0x00, 7, // 0x71 'q' 0x00,0x00,0x00,0x00,0x7c,0xcc,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0x0c,0x0c,0x00, 7, // 0x72 'r' 0x00,0x00,0x00,0x00,0xd8,0xec,0xcc,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00, 7, // 0x73 's' 0x00,0x00,0x00,0x00,0x78,0xcc,0xe0,0x70,0x38,0x1c,0xcc,0x78,0x00,0x00,0x00, 7, // 0x74 't' 0x00,0x00,0x20,0x60,0x60,0xf0,0x60,0x60,0x60,0x60,0x6c,0x38,0x00,0x00,0x00, 7, // 0x75 'u' 0x00,0x00,0x00,0x00,0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,0x6c,0x00,0x00,0x00, 7, // 0x76 'v' 0x00,0x00,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x78,0x30,0x00,0x00,0x00, 7, // 0x77 'w' 0x00,0x00,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xb4,0xfc,0xcc,0x84,0x00,0x00,0x00, 7, // 0x78 'x' 0x00,0x00,0x00,0x00,0xcc,0xcc,0x78,0x30,0x78,0xcc,0xcc,0xcc,0x00,0x00,0x00, 7, // 0x79 'y' 0x00,0x00,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0x18,0xf0,0x00, 7, // 0x7a 'z' 0x00,0x00,0x00,0x00,0xfc,0x8c,0x18,0x30,0x60,0xc0,0xc4,0xfc,0x00,0x00,0x00, 7, // 0x7b '{' 0x00,0x1c,0x30,0x30,0x30,0x30,0x30,0xe0,0x30,0x30,0x30,0x30,0x1c,0x00,0x00, 7, // 0x7c '|' 0x00,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x30,0x30,0x30,0x30,0x30,0x00,0x00, 7, // 0x7d '}' 0x00,0xe0,0x30,0x30,0x30,0x30,0x30,0x1c,0x30,0x30,0x30,0x30,0xe0,0x00,0x00, 7, // 0x7e '~' 0x00,0x00,0x34,0x58,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x7f '' 0x00,0x00,0x00,0x00,0x00,0x30,0x78,0xcc,0xcc,0xfc,0x00,0x00,0x00,0x00,0x00, 0 }; const int8u gse8x16[] = { 16, 0, 32, 128-32, 0x00,0x00,0x11,0x00,0x22,0x00,0x33,0x00,0x44,0x00,0x55,0x00,0x66,0x00,0x77,0x00,0x88,0x00, 0x99,0x00,0xaa,0x00,0xbb,0x00,0xcc,0x00,0xdd,0x00,0xee,0x00,0xff,0x00,0x10,0x01,0x21,0x01, 0x32,0x01,0x43,0x01,0x54,0x01,0x65,0x01,0x76,0x01,0x87,0x01,0x98,0x01,0xa9,0x01,0xba,0x01, 0xcb,0x01,0xdc,0x01,0xed,0x01,0xfe,0x01,0x0f,0x02,0x20,0x02,0x31,0x02,0x42,0x02,0x53,0x02, 0x64,0x02,0x75,0x02,0x86,0x02,0x97,0x02,0xa8,0x02,0xb9,0x02,0xca,0x02,0xdb,0x02,0xec,0x02, 0xfd,0x02,0x0e,0x03,0x1f,0x03,0x30,0x03,0x41,0x03,0x52,0x03,0x63,0x03,0x74,0x03,0x85,0x03, 0x96,0x03,0xa7,0x03,0xb8,0x03,0xc9,0x03,0xda,0x03,0xeb,0x03,0xfc,0x03,0x0d,0x04,0x1e,0x04, 0x2f,0x04,0x40,0x04,0x51,0x04,0x62,0x04,0x73,0x04,0x84,0x04,0x95,0x04,0xa6,0x04,0xb7,0x04, 0xc8,0x04,0xd9,0x04,0xea,0x04,0xfb,0x04,0x0c,0x05,0x1d,0x05,0x2e,0x05,0x3f,0x05,0x50,0x05, 0x61,0x05,0x72,0x05,0x83,0x05,0x94,0x05,0xa5,0x05,0xb6,0x05,0xc7,0x05,0xd8,0x05,0xe9,0x05, 0xfa,0x05,0x0b,0x06,0x1c,0x06,0x2d,0x06,0x3e,0x06,0x4f,0x06, 8, // 0x20 ' ' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x21 '!' 0x00,0x00,0x10,0x38,0x38,0x38,0x38,0x10,0x10,0x00,0x10,0x10,0x00,0x00,0x00,0x00, 8, // 0x22 '"' 0x00,0x24,0x24,0x24,0x24,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x23 '#' 0x00,0x00,0x24,0x24,0x24,0x7e,0x24,0x24,0x7e,0x24,0x24,0x24,0x00,0x00,0x00,0x00, 8, // 0x24 '$' 0x00,0x14,0x14,0x3e,0x55,0x54,0x54,0x3e,0x15,0x15,0x55,0x3e,0x14,0x14,0x00,0x00, 8, // 0x25 '%' 0x00,0x00,0x32,0x56,0x6c,0x04,0x08,0x08,0x10,0x13,0x25,0x26,0x00,0x00,0x00,0x00, 8, // 0x26 '&' 0x00,0x00,0x18,0x24,0x24,0x24,0x18,0x28,0x45,0x46,0x44,0x3b,0x00,0x00,0x00,0x00, 8, // 0x27 ''' 0x00,0x00,0x08,0x08,0x08,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x28 '(' 0x00,0x04,0x08,0x10,0x10,0x20,0x20,0x20,0x20,0x10,0x10,0x08,0x04,0x00,0x00,0x00, 8, // 0x29 ')' 0x00,0x10,0x08,0x04,0x04,0x02,0x02,0x02,0x02,0x04,0x04,0x08,0x10,0x00,0x00,0x00, 8, // 0x2a '*' 0x00,0x00,0x00,0x00,0x66,0x24,0x18,0xff,0x18,0x24,0x66,0x00,0x00,0x00,0x00,0x00, 8, // 0x2b '+' 0x00,0x00,0x00,0x00,0x08,0x08,0x08,0x7f,0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00, 8, // 0x2c ',' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x20,0x00, 8, // 0x2d '-' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x2e '.' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00, 8, // 0x2f '/' 0x00,0x02,0x02,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x00,0x00,0x00, 8, // 0x30 '0' 0x00,0x00,0x3c,0x42,0x42,0x46,0x4a,0x52,0x62,0x42,0x42,0x3c,0x00,0x00,0x00,0x00, 8, // 0x31 '1' 0x00,0x00,0x08,0x08,0x18,0x38,0x08,0x08,0x08,0x08,0x08,0x3e,0x00,0x00,0x00,0x00, 8, // 0x32 '2' 0x00,0x00,0x3c,0x42,0x42,0x02,0x04,0x08,0x10,0x20,0x42,0x7e,0x00,0x00,0x00,0x00, 8, // 0x33 '3' 0x00,0x00,0x7e,0x42,0x04,0x08,0x1c,0x02,0x02,0x02,0x42,0x3c,0x00,0x00,0x00,0x00, 8, // 0x34 '4' 0x00,0x00,0x04,0x08,0x10,0x24,0x44,0x44,0x7e,0x04,0x04,0x0e,0x00,0x00,0x00,0x00, 8, // 0x35 '5' 0x00,0x00,0x7e,0x42,0x40,0x40,0x7c,0x02,0x02,0x02,0x42,0x3c,0x00,0x00,0x00,0x00, 8, // 0x36 '6' 0x00,0x00,0x1c,0x20,0x40,0x40,0x7c,0x42,0x42,0x42,0x42,0x3c,0x00,0x00,0x00,0x00, 8, // 0x37 '7' 0x00,0x00,0x7e,0x42,0x42,0x02,0x04,0x08,0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x00, 8, // 0x38 '8' 0x00,0x00,0x3c,0x42,0x42,0x42,0x3c,0x42,0x42,0x42,0x42,0x3c,0x00,0x00,0x00,0x00, 8, // 0x39 '9' 0x00,0x00,0x3c,0x42,0x42,0x42,0x42,0x3e,0x02,0x02,0x04,0x38,0x00,0x00,0x00,0x00, 8, // 0x3a ':' 0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x3b ';' 0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x60,0x40,0x00, 8, // 0x3c '<' 0x00,0x00,0x00,0x02,0x04,0x08,0x10,0x20,0x10,0x08,0x04,0x02,0x00,0x00,0x00,0x00, 8, // 0x3d '=' 0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x3e '>' 0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x04,0x08,0x10,0x20,0x00,0x00,0x00,0x00, 8, // 0x3f '?' 0x00,0x00,0x3c,0x42,0x42,0x42,0x04,0x08,0x08,0x00,0x08,0x08,0x00,0x00,0x00,0x00, 8, // 0x40 '@' 0x00,0x00,0x3c,0x42,0x01,0x39,0x49,0x49,0x49,0x49,0x49,0x36,0x00,0x00,0x00,0x00, 8, // 0x41 'A' 0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x7e,0x42,0x42,0x42,0x42,0x00,0x00,0x00,0x00, 8, // 0x42 'B' 0x00,0x00,0x7c,0x22,0x22,0x22,0x3c,0x22,0x22,0x22,0x22,0x7c,0x00,0x00,0x00,0x00, 8, // 0x43 'C' 0x00,0x00,0x3c,0x42,0x42,0x40,0x40,0x40,0x40,0x42,0x42,0x3c,0x00,0x00,0x00,0x00, 8, // 0x44 'D' 0x00,0x00,0x7c,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x7c,0x00,0x00,0x00,0x00, 8, // 0x45 'E' 0x00,0x00,0x7e,0x22,0x20,0x28,0x38,0x28,0x20,0x20,0x22,0x7e,0x00,0x00,0x00,0x00, 8, // 0x46 'F' 0x00,0x00,0x7e,0x22,0x20,0x28,0x38,0x28,0x20,0x20,0x20,0x70,0x00,0x00,0x00,0x00, 8, // 0x47 'G' 0x00,0x00,0x3c,0x42,0x42,0x40,0x40,0x4e,0x42,0x42,0x42,0x3c,0x00,0x00,0x00,0x00, 8, // 0x48 'H' 0x00,0x00,0x42,0x42,0x42,0x42,0x7e,0x42,0x42,0x42,0x42,0x42,0x00,0x00,0x00,0x00, 8, // 0x49 'I' 0x00,0x00,0x1c,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x1c,0x00,0x00,0x00,0x00, 8, // 0x4a 'J' 0x00,0x00,0x0e,0x04,0x04,0x04,0x04,0x04,0x04,0x44,0x44,0x38,0x00,0x00,0x00,0x00, 8, // 0x4b 'K' 0x00,0x00,0x62,0x22,0x24,0x28,0x30,0x28,0x24,0x22,0x22,0x62,0x00,0x00,0x00,0x00, 8, // 0x4c 'L' 0x00,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x22,0x7e,0x00,0x00,0x00,0x00, 8, // 0x4d 'M' 0x00,0x00,0x41,0x63,0x55,0x49,0x41,0x41,0x41,0x41,0x41,0x41,0x00,0x00,0x00,0x00, 8, // 0x4e 'N' 0x00,0x00,0x42,0x42,0x62,0x52,0x4a,0x46,0x42,0x42,0x42,0x42,0x00,0x00,0x00,0x00, 8, // 0x4f 'O' 0x00,0x00,0x3c,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x3c,0x00,0x00,0x00,0x00, 8, // 0x50 'P' 0x00,0x00,0x7c,0x22,0x22,0x22,0x22,0x3c,0x20,0x20,0x20,0x70,0x00,0x00,0x00,0x00, 8, // 0x51 'Q' 0x00,0x00,0x3c,0x42,0x42,0x42,0x42,0x42,0x42,0x4a,0x44,0x3a,0x02,0x00,0x00,0x00, 8, // 0x52 'R' 0x00,0x00,0x7c,0x22,0x22,0x22,0x22,0x3c,0x28,0x24,0x22,0x62,0x00,0x00,0x00,0x00, 8, // 0x53 'S' 0x00,0x00,0x3c,0x42,0x42,0x40,0x30,0x0c,0x02,0x42,0x42,0x3c,0x00,0x00,0x00,0x00, 8, // 0x54 'T' 0x00,0x00,0x7f,0x49,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x1c,0x00,0x00,0x00,0x00, 8, // 0x55 'U' 0x00,0x00,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x3c,0x00,0x00,0x00,0x00, 8, // 0x56 'V' 0x00,0x00,0x41,0x41,0x41,0x41,0x22,0x22,0x14,0x14,0x08,0x08,0x00,0x00,0x00,0x00, 8, // 0x57 'W' 0x00,0x00,0x41,0x41,0x41,0x41,0x41,0x49,0x49,0x55,0x63,0x41,0x00,0x00,0x00,0x00, 8, // 0x58 'X' 0x00,0x00,0x42,0x42,0x42,0x24,0x18,0x18,0x24,0x42,0x42,0x42,0x00,0x00,0x00,0x00, 8, // 0x59 'Y' 0x00,0x00,0x22,0x22,0x22,0x22,0x14,0x08,0x08,0x08,0x08,0x1c,0x00,0x00,0x00,0x00, 8, // 0x5a 'Z' 0x00,0x00,0x7e,0x42,0x02,0x04,0x08,0x10,0x20,0x40,0x42,0x7e,0x00,0x00,0x00,0x00, 8, // 0x5b '[' 0x00,0x1e,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x1e,0x00,0x00,0x00, 8, // 0x5c '\' 0x00,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x02,0x02,0x00,0x00,0x00, 8, // 0x5d ']' 0x00,0x3c,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x3c,0x00,0x00,0x00, 8, // 0x5e '^' 0x00,0x00,0x08,0x14,0x22,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x5f '_' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x00, 8, // 0x60 '`' 0x00,0x00,0x08,0x08,0x08,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x61 'a' 0x00,0x00,0x00,0x00,0x00,0x38,0x44,0x04,0x3c,0x44,0x44,0x3e,0x00,0x00,0x00,0x00, 8, // 0x62 'b' 0x00,0x00,0x60,0x20,0x20,0x38,0x24,0x22,0x22,0x22,0x22,0x3c,0x00,0x00,0x00,0x00, 8, // 0x63 'c' 0x00,0x00,0x00,0x00,0x00,0x3c,0x42,0x40,0x40,0x40,0x42,0x3c,0x00,0x00,0x00,0x00, 8, // 0x64 'd' 0x00,0x00,0x0c,0x04,0x04,0x1c,0x24,0x44,0x44,0x44,0x44,0x3e,0x00,0x00,0x00,0x00, 8, // 0x65 'e' 0x00,0x00,0x00,0x00,0x00,0x3c,0x42,0x42,0x7e,0x40,0x42,0x3c,0x00,0x00,0x00,0x00, 8, // 0x66 'f' 0x00,0x00,0x0c,0x12,0x10,0x10,0x38,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00,0x00, 8, // 0x67 'g' 0x00,0x00,0x00,0x00,0x00,0x3e,0x44,0x44,0x44,0x44,0x44,0x3c,0x04,0x44,0x38,0x00, 8, // 0x68 'h' 0x00,0x00,0x60,0x20,0x20,0x2c,0x32,0x22,0x22,0x22,0x22,0x62,0x00,0x00,0x00,0x00, 8, // 0x69 'i' 0x00,0x00,0x08,0x08,0x00,0x18,0x08,0x08,0x08,0x08,0x08,0x1c,0x00,0x00,0x00,0x00, 8, // 0x6a 'j' 0x00,0x00,0x04,0x04,0x00,0x0c,0x04,0x04,0x04,0x04,0x04,0x44,0x44,0x38,0x00,0x00, 8, // 0x6b 'k' 0x00,0x00,0x60,0x20,0x20,0x22,0x24,0x28,0x38,0x24,0x22,0x62,0x00,0x00,0x00,0x00, 8, // 0x6c 'l' 0x00,0x00,0x18,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x1c,0x00,0x00,0x00,0x00, 8, // 0x6d 'm' 0x00,0x00,0x00,0x00,0x00,0x76,0x49,0x49,0x49,0x49,0x41,0x41,0x00,0x00,0x00,0x00, 8, // 0x6e 'n' 0x00,0x00,0x00,0x00,0x00,0x5c,0x22,0x22,0x22,0x22,0x22,0x22,0x00,0x00,0x00,0x00, 8, // 0x6f 'o' 0x00,0x00,0x00,0x00,0x00,0x3c,0x42,0x42,0x42,0x42,0x42,0x3c,0x00,0x00,0x00,0x00, 8, // 0x70 'p' 0x00,0x00,0x00,0x00,0x00,0x7c,0x22,0x22,0x22,0x22,0x22,0x3c,0x20,0x20,0x70,0x00, 8, // 0x71 'q' 0x00,0x00,0x00,0x00,0x00,0x3e,0x44,0x44,0x44,0x44,0x44,0x3c,0x04,0x04,0x0e,0x00, 8, // 0x72 'r' 0x00,0x00,0x00,0x00,0x00,0x7c,0x22,0x22,0x20,0x20,0x20,0x70,0x00,0x00,0x00,0x00, 8, // 0x73 's' 0x00,0x00,0x00,0x00,0x00,0x3c,0x42,0x40,0x3c,0x02,0x42,0x3c,0x00,0x00,0x00,0x00, 8, // 0x74 't' 0x00,0x00,0x10,0x10,0x10,0x7c,0x10,0x10,0x10,0x10,0x12,0x0c,0x00,0x00,0x00,0x00, 8, // 0x75 'u' 0x00,0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x3e,0x00,0x00,0x00,0x00, 8, // 0x76 'v' 0x00,0x00,0x00,0x00,0x00,0x41,0x41,0x41,0x41,0x22,0x14,0x08,0x00,0x00,0x00,0x00, 8, // 0x77 'w' 0x00,0x00,0x00,0x00,0x00,0x41,0x41,0x41,0x49,0x49,0x55,0x22,0x00,0x00,0x00,0x00, 8, // 0x78 'x' 0x00,0x00,0x00,0x00,0x00,0x42,0x42,0x24,0x18,0x24,0x42,0x42,0x00,0x00,0x00,0x00, 8, // 0x79 'y' 0x00,0x00,0x00,0x00,0x00,0x42,0x42,0x42,0x42,0x42,0x42,0x3e,0x02,0x04,0x78,0x00, 8, // 0x7a 'z' 0x00,0x00,0x00,0x00,0x00,0x7e,0x44,0x08,0x10,0x20,0x42,0x7e,0x00,0x00,0x00,0x00, 8, // 0x7b '{' 0x00,0x06,0x08,0x08,0x08,0x08,0x08,0x30,0x08,0x08,0x08,0x08,0x08,0x06,0x00,0x00, 8, // 0x7c '|' 0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x00,0x08,0x08,0x08,0x08,0x08,0x00,0x00,0x00, 8, // 0x7d '}' 0x00,0x30,0x08,0x08,0x08,0x08,0x08,0x06,0x08,0x08,0x08,0x08,0x08,0x30,0x00,0x00, 8, // 0x7e '~' 0x00,0x00,0x39,0x4e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x7f '' 0x00,0x00,0x00,0x00,0x00,0x08,0x14,0x22,0x41,0x41,0x7f,0x00,0x00,0x00,0x00,0x00, 0 }; const int8u gse8x16_bold[] = { 16, 0, 32, 128-32, 0x00,0x00,0x11,0x00,0x22,0x00,0x33,0x00,0x44,0x00,0x55,0x00,0x66,0x00,0x77,0x00,0x88,0x00, 0x99,0x00,0xaa,0x00,0xbb,0x00,0xcc,0x00,0xdd,0x00,0xee,0x00,0xff,0x00,0x10,0x01,0x21,0x01, 0x32,0x01,0x43,0x01,0x54,0x01,0x65,0x01,0x76,0x01,0x87,0x01,0x98,0x01,0xa9,0x01,0xba,0x01, 0xcb,0x01,0xdc,0x01,0xed,0x01,0xfe,0x01,0x0f,0x02,0x20,0x02,0x31,0x02,0x42,0x02,0x53,0x02, 0x64,0x02,0x75,0x02,0x86,0x02,0x97,0x02,0xa8,0x02,0xb9,0x02,0xca,0x02,0xdb,0x02,0xec,0x02, 0xfd,0x02,0x0e,0x03,0x1f,0x03,0x30,0x03,0x41,0x03,0x52,0x03,0x63,0x03,0x74,0x03,0x85,0x03, 0x96,0x03,0xa7,0x03,0xb8,0x03,0xc9,0x03,0xda,0x03,0xeb,0x03,0xfc,0x03,0x0d,0x04,0x1e,0x04, 0x2f,0x04,0x40,0x04,0x51,0x04,0x62,0x04,0x73,0x04,0x84,0x04,0x95,0x04,0xa6,0x04,0xb7,0x04, 0xc8,0x04,0xd9,0x04,0xea,0x04,0xfb,0x04,0x0c,0x05,0x1d,0x05,0x2e,0x05,0x3f,0x05,0x50,0x05, 0x61,0x05,0x72,0x05,0x83,0x05,0x94,0x05,0xa5,0x05,0xb6,0x05,0xc7,0x05,0xd8,0x05,0xe9,0x05, 0xfa,0x05,0x0b,0x06,0x1c,0x06,0x2d,0x06,0x3e,0x06,0x4f,0x06, 8, // 0x20 ' ' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x21 '!' 0x00,0x00,0x18,0x3c,0x3c,0x3c,0x3c,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00, 8, // 0x22 '"' 0x00,0x66,0x66,0x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x23 '#' 0x00,0x00,0x66,0x66,0x66,0xff,0x66,0x66,0xff,0x66,0x66,0x66,0x00,0x00,0x00,0x00, 8, // 0x24 '$' 0x00,0x08,0x08,0x3e,0x6b,0x6b,0x68,0x3e,0x0b,0x6b,0x6b,0x3e,0x08,0x08,0x00,0x00, 8, // 0x25 '%' 0x00,0x00,0x66,0xbe,0xcc,0x0c,0x18,0x18,0x30,0x33,0x65,0x66,0x00,0x00,0x00,0x00, 8, // 0x26 '&' 0x00,0x00,0x1c,0x36,0x36,0x36,0x1c,0x3b,0x6e,0x66,0x66,0x3b,0x00,0x00,0x00,0x00, 8, // 0x27 ''' 0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x28 '(' 0x00,0x06,0x0c,0x18,0x18,0x30,0x30,0x30,0x30,0x18,0x18,0x0c,0x06,0x00,0x00,0x00, 8, // 0x29 ')' 0x00,0x30,0x18,0x0c,0x0c,0x06,0x06,0x06,0x06,0x0c,0x0c,0x18,0x30,0x00,0x00,0x00, 8, // 0x2a '*' 0x00,0x00,0x00,0x00,0x66,0x24,0x18,0xff,0x18,0x24,0x66,0x00,0x00,0x00,0x00,0x00, 8, // 0x2b '+' 0x00,0x00,0x00,0x00,0x18,0x18,0x18,0xff,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00, 8, // 0x2c ',' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x20,0x00, 8, // 0x2d '-' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x2e '.' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00, 8, // 0x2f '/' 0x00,0x03,0x03,0x06,0x06,0x0c,0x0c,0x18,0x18,0x30,0x30,0x60,0x60,0x00,0x00,0x00, 8, // 0x30 '0' 0x00,0x00,0x3e,0x63,0x63,0x67,0x6b,0x73,0x63,0x63,0x63,0x3e,0x00,0x00,0x00,0x00, 8, // 0x31 '1' 0x00,0x00,0x0c,0x0c,0x1c,0x3c,0x0c,0x0c,0x0c,0x0c,0x0c,0x3f,0x00,0x00,0x00,0x00, 8, // 0x32 '2' 0x00,0x00,0x3e,0x63,0x63,0x03,0x06,0x0c,0x18,0x30,0x61,0x7f,0x00,0x00,0x00,0x00, 8, // 0x33 '3' 0x00,0x00,0x7f,0x43,0x06,0x0c,0x1e,0x03,0x03,0x03,0x63,0x3e,0x00,0x00,0x00,0x00, 8, // 0x34 '4' 0x00,0x00,0x06,0x0c,0x18,0x32,0x66,0x66,0x7f,0x06,0x06,0x0f,0x00,0x00,0x00,0x00, 8, // 0x35 '5' 0x00,0x00,0x7f,0x61,0x60,0x60,0x7e,0x03,0x03,0x03,0x63,0x3e,0x00,0x00,0x00,0x00, 8, // 0x36 '6' 0x00,0x00,0x1e,0x30,0x60,0x60,0x7e,0x63,0x63,0x63,0x63,0x3e,0x00,0x00,0x00,0x00, 8, // 0x37 '7' 0x00,0x00,0x7f,0x63,0x63,0x03,0x06,0x0c,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, 8, // 0x38 '8' 0x00,0x00,0x3e,0x63,0x63,0x63,0x3e,0x63,0x63,0x63,0x63,0x3e,0x00,0x00,0x00,0x00, 8, // 0x39 '9' 0x00,0x00,0x3e,0x63,0x63,0x63,0x63,0x3f,0x03,0x03,0x06,0x3c,0x00,0x00,0x00,0x00, 8, // 0x3a ':' 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00, 8, // 0x3b ';' 0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x60,0x40,0x00, 8, // 0x3c '<' 0x00,0x00,0x00,0x06,0x0c,0x18,0x30,0x60,0x30,0x18,0x0c,0x06,0x00,0x00,0x00,0x00, 8, // 0x3d '=' 0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x3e '>' 0x00,0x00,0x00,0x30,0x18,0x0c,0x06,0x03,0x06,0x0c,0x18,0x30,0x00,0x00,0x00,0x00, 8, // 0x3f '?' 0x00,0x00,0x3e,0x63,0x63,0x63,0x06,0x0c,0x0c,0x00,0x0c,0x0c,0x00,0x00,0x00,0x00, 8, // 0x40 '@' 0x00,0x00,0x7c,0x86,0x03,0x73,0xdb,0xdb,0xdb,0xdb,0xdb,0x6e,0x00,0x00,0x00,0x00, 8, // 0x41 'A' 0x00,0x00,0x08,0x1c,0x36,0x63,0x63,0x63,0x7f,0x63,0x63,0x63,0x00,0x00,0x00,0x00, 8, // 0x42 'B' 0x00,0x00,0x7e,0x33,0x33,0x33,0x3e,0x33,0x33,0x33,0x33,0x7e,0x00,0x00,0x00,0x00, 8, // 0x43 'C' 0x00,0x00,0x1e,0x33,0x61,0x60,0x60,0x60,0x60,0x61,0x33,0x1e,0x00,0x00,0x00,0x00, 8, // 0x44 'D' 0x00,0x00,0x7c,0x36,0x33,0x33,0x33,0x33,0x33,0x33,0x36,0x7c,0x00,0x00,0x00,0x00, 8, // 0x45 'E' 0x00,0x00,0x7f,0x33,0x31,0x34,0x3c,0x34,0x30,0x31,0x33,0x7f,0x00,0x00,0x00,0x00, 8, // 0x46 'F' 0x00,0x00,0x7f,0x33,0x31,0x34,0x3c,0x34,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00, 8, // 0x47 'G' 0x00,0x00,0x1f,0x33,0x61,0x60,0x60,0x6f,0x63,0x63,0x33,0x1e,0x00,0x00,0x00,0x00, 8, // 0x48 'H' 0x00,0x00,0x63,0x63,0x63,0x63,0x7f,0x63,0x63,0x63,0x63,0x63,0x00,0x00,0x00,0x00, 8, // 0x49 'I' 0x00,0x00,0x1e,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x00,0x00, 8, // 0x4a 'J' 0x00,0x00,0x0f,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3c,0x00,0x00,0x00,0x00, 8, // 0x4b 'K' 0x00,0x00,0x73,0x33,0x36,0x36,0x3c,0x36,0x36,0x33,0x33,0x73,0x00,0x00,0x00,0x00, 8, // 0x4c 'L' 0x00,0x00,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x33,0x7f,0x00,0x00,0x00,0x00, 8, // 0x4d 'M' 0x00,0x00,0x63,0x63,0x77,0x77,0x7f,0x6b,0x6b,0x63,0x63,0x63,0x00,0x00,0x00,0x00, 8, // 0x4e 'N' 0x00,0x00,0x63,0x63,0x73,0x7b,0x6f,0x67,0x63,0x63,0x63,0x63,0x00,0x00,0x00,0x00, 8, // 0x4f 'O' 0x00,0x00,0x1c,0x36,0x63,0x63,0x63,0x63,0x63,0x63,0x36,0x1c,0x00,0x00,0x00,0x00, 8, // 0x50 'P' 0x00,0x00,0x7e,0x33,0x33,0x33,0x33,0x3e,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00, 8, // 0x51 'Q' 0x00,0x00,0x1c,0x36,0x63,0x63,0x63,0x63,0x63,0x6f,0x36,0x1e,0x03,0x00,0x00,0x00, 8, // 0x52 'R' 0x00,0x00,0x7e,0x33,0x33,0x33,0x33,0x3e,0x36,0x33,0x33,0x73,0x00,0x00,0x00,0x00, 8, // 0x53 'S' 0x00,0x00,0x3e,0x63,0x63,0x30,0x18,0x0c,0x06,0x63,0x63,0x3e,0x00,0x00,0x00,0x00, 8, // 0x54 'T' 0x00,0x00,0x3f,0x3f,0x2d,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x00,0x00, 8, // 0x55 'U' 0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x3e,0x00,0x00,0x00,0x00, 8, // 0x56 'V' 0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x36,0x1c,0x08,0x00,0x00,0x00,0x00, 8, // 0x57 'W' 0x00,0x00,0x63,0x63,0x63,0x6b,0x6b,0x7f,0x77,0x77,0x63,0x63,0x00,0x00,0x00,0x00, 8, // 0x58 'X' 0x00,0x00,0x63,0x63,0x63,0x36,0x1c,0x1c,0x36,0x63,0x63,0x63,0x00,0x00,0x00,0x00, 8, // 0x59 'Y' 0x00,0x00,0x33,0x33,0x33,0x33,0x1e,0x0c,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x00,0x00, 8, // 0x5a 'Z' 0x00,0x00,0x7f,0x63,0x43,0x06,0x0c,0x18,0x30,0x61,0x63,0x7f,0x00,0x00,0x00,0x00, 8, // 0x5b '[' 0x00,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x00,0x00,0x00, 8, // 0x5c '\' 0x00,0x60,0x60,0x30,0x30,0x18,0x18,0x0c,0x0c,0x06,0x06,0x03,0x03,0x00,0x00,0x00, 8, // 0x5d ']' 0x00,0x7c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x7c,0x00,0x00,0x00, 8, // 0x5e '^' 0x00,0x00,0x08,0x1c,0x36,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x5f '_' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x00, 8, // 0x60 '`' 0x00,0x00,0x18,0x18,0x18,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x61 'a' 0x00,0x00,0x00,0x00,0x00,0x3c,0x66,0x06,0x3e,0x66,0x66,0x3b,0x00,0x00,0x00,0x00, 8, // 0x62 'b' 0x00,0x00,0x70,0x30,0x30,0x3c,0x36,0x33,0x33,0x33,0x33,0x3e,0x00,0x00,0x00,0x00, 8, // 0x63 'c' 0x00,0x00,0x00,0x00,0x00,0x3e,0x63,0x63,0x60,0x60,0x63,0x3e,0x00,0x00,0x00,0x00, 8, // 0x64 'd' 0x00,0x00,0x0e,0x06,0x06,0x1e,0x36,0x66,0x66,0x66,0x66,0x3b,0x00,0x00,0x00,0x00, 8, // 0x65 'e' 0x00,0x00,0x00,0x00,0x00,0x3e,0x63,0x63,0x7f,0x60,0x63,0x3e,0x00,0x00,0x00,0x00, 8, // 0x66 'f' 0x00,0x00,0x0e,0x1b,0x1b,0x18,0x3c,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, 8, // 0x67 'g' 0x00,0x00,0x00,0x00,0x00,0x3b,0x66,0x66,0x66,0x66,0x66,0x3e,0x06,0x66,0x3c,0x00, 8, // 0x68 'h' 0x00,0x00,0x70,0x30,0x30,0x36,0x3b,0x33,0x33,0x33,0x33,0x73,0x00,0x00,0x00,0x00, 8, // 0x69 'i' 0x00,0x00,0x0c,0x0c,0x00,0x1c,0x0c,0x0c,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x00,0x00, 8, // 0x6a 'j' 0x00,0x00,0x06,0x06,0x00,0x0e,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3c,0x00,0x00, 8, // 0x6b 'k' 0x00,0x00,0x70,0x30,0x30,0x33,0x33,0x36,0x3c,0x36,0x33,0x73,0x00,0x00,0x00,0x00, 8, // 0x6c 'l' 0x00,0x00,0x1c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x00,0x00, 8, // 0x6d 'm' 0x00,0x00,0x00,0x00,0x00,0x76,0x7f,0x6b,0x6b,0x6b,0x63,0x63,0x00,0x00,0x00,0x00, 8, // 0x6e 'n' 0x00,0x00,0x00,0x00,0x00,0x6e,0x33,0x33,0x33,0x33,0x33,0x33,0x00,0x00,0x00,0x00, 8, // 0x6f 'o' 0x00,0x00,0x00,0x00,0x00,0x3e,0x63,0x63,0x63,0x63,0x63,0x3e,0x00,0x00,0x00,0x00, 8, // 0x70 'p' 0x00,0x00,0x00,0x00,0x00,0x6e,0x33,0x33,0x33,0x33,0x33,0x3e,0x30,0x30,0x78,0x00, 8, // 0x71 'q' 0x00,0x00,0x00,0x00,0x00,0x3b,0x66,0x66,0x66,0x66,0x66,0x3e,0x06,0x06,0x0f,0x00, 8, // 0x72 'r' 0x00,0x00,0x00,0x00,0x00,0x6e,0x3b,0x33,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00, 8, // 0x73 's' 0x00,0x00,0x00,0x00,0x00,0x3e,0x63,0x60,0x3e,0x03,0x63,0x3e,0x00,0x00,0x00,0x00, 8, // 0x74 't' 0x00,0x00,0x08,0x18,0x18,0x7e,0x18,0x18,0x18,0x18,0x1b,0x0e,0x00,0x00,0x00,0x00, 8, // 0x75 'u' 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x3b,0x00,0x00,0x00,0x00, 8, // 0x76 'v' 0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x63,0x63,0x36,0x1c,0x08,0x00,0x00,0x00,0x00, 8, // 0x77 'w' 0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x6b,0x6b,0x7f,0x36,0x36,0x00,0x00,0x00,0x00, 8, // 0x78 'x' 0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x36,0x1c,0x36,0x63,0x63,0x00,0x00,0x00,0x00, 8, // 0x79 'y' 0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63,0x3f,0x03,0x06,0x7c,0x00, 8, // 0x7a 'z' 0x00,0x00,0x00,0x00,0x00,0x7f,0x63,0x06,0x0c,0x18,0x31,0x7f,0x00,0x00,0x00,0x00, 8, // 0x7b '{' 0x00,0x03,0x04,0x0c,0x0c,0x0c,0x08,0x30,0x08,0x0c,0x0c,0x0c,0x04,0x03,0x00,0x00, 8, // 0x7c '|' 0x00,0x00,0x0c,0x0c,0x0c,0x0c,0x0c,0x00,0x0c,0x0c,0x0c,0x0c,0x0c,0x00,0x00,0x00, 8, // 0x7d '}' 0x00,0x60,0x10,0x18,0x18,0x18,0x08,0x06,0x08,0x18,0x18,0x18,0x10,0x60,0x00,0x00, 8, // 0x7e '~' 0x00,0x00,0x3b,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x7f '' 0x00,0x00,0x00,0x00,0x00,0x08,0x1c,0x36,0x63,0x63,0x7f,0x00,0x00,0x00,0x00,0x00, 0 }; const int8u mcs11_prop[] = { 11, 2, 32, 128-32, 0x00,0x00,0x0C,0x00,0x18,0x00,0x24,0x00,0x30,0x00,0x3C,0x00,0x48,0x00,0x54,0x00,0x60,0x00, 0x6C,0x00,0x78,0x00,0x84,0x00,0x90,0x00,0x9C,0x00,0xA8,0x00,0xB4,0x00,0xC0,0x00,0xCC,0x00, 0xD8,0x00,0xE4,0x00,0xF0,0x00,0xFC,0x00,0x08,0x01,0x14,0x01,0x20,0x01,0x2C,0x01,0x38,0x01, 0x44,0x01,0x50,0x01,0x5C,0x01,0x68,0x01,0x74,0x01,0x80,0x01,0x8C,0x01,0x98,0x01,0xA4,0x01, 0xB0,0x01,0xBC,0x01,0xC8,0x01,0xD4,0x01,0xE0,0x01,0xEC,0x01,0xF8,0x01,0x04,0x02,0x10,0x02, 0x1C,0x02,0x28,0x02,0x34,0x02,0x40,0x02,0x4C,0x02,0x58,0x02,0x64,0x02,0x70,0x02,0x7C,0x02, 0x88,0x02,0x94,0x02,0xA0,0x02,0xAC,0x02,0xB8,0x02,0xC4,0x02,0xD0,0x02,0xDC,0x02,0xE8,0x02, 0xF4,0x02,0x00,0x03,0x0C,0x03,0x18,0x03,0x24,0x03,0x30,0x03,0x3C,0x03,0x48,0x03,0x54,0x03, 0x60,0x03,0x6C,0x03,0x78,0x03,0x84,0x03,0x90,0x03,0x9C,0x03,0xA8,0x03,0xB4,0x03,0xC0,0x03, 0xCC,0x03,0xD8,0x03,0xE4,0x03,0xF0,0x03,0xFC,0x03,0x08,0x04,0x14,0x04,0x20,0x04,0x2C,0x04, 0x38,0x04,0x44,0x04,0x50,0x04,0x5C,0x04,0x68,0x04,0x74,0x04, 5, // 0x20 ' ' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 4, // 0x21 '!' 0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00, 4, // 0x22 '"' 0x50,0x50,0xA0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x23 '#' 0x00,0x28,0x28,0x7C,0x28,0x28,0x28,0x7C,0x28,0x28,0x00, 6, // 0x24 '$' 0x10,0x10,0x38,0x54,0x50,0x38,0x14,0x54,0x38,0x10,0x10, 6, // 0x25 '%' 0x00,0x00,0x68,0xA8,0xD0,0x10,0x20,0x2C,0x54,0x58,0x00, 6, // 0x26 '&' 0x00,0x20,0x50,0x50,0x50,0x20,0x54,0x54,0x48,0x34,0x00, 3, // 0x27 ''' 0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 4, // 0x28 '(' 0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x10, 5, // 0x29 ')' 0x40,0x20,0x20,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x40, 6, // 0x2A '*' 0x00,0x00,0x28,0x7C,0x38,0x7C,0x28,0x00,0x00,0x00,0x00, 6, // 0x2B '+' 0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00,0x00, 4, // 0x2C ',' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0xC0, 6, // 0x2D '-' 0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00, 4, // 0x2E '.' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00, 7, // 0x2F '/' 0x00,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40, 6, // 0x30 '0' 0x00,0x38,0x44,0x44,0x54,0x54,0x54,0x44,0x44,0x38,0x00, 4, // 0x31 '1' 0x00,0x20,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00, 6, // 0x32 '2' 0x00,0x38,0x44,0x44,0x04,0x08,0x10,0x20,0x40,0x7C,0x00, 6, // 0x33 '3' 0x00,0x38,0x44,0x04,0x04,0x38,0x04,0x04,0x44,0x38,0x00, 6, // 0x34 '4' 0x00,0x08,0x18,0x18,0x28,0x28,0x48,0x7C,0x08,0x08,0x00, 6, // 0x35 '5' 0x00,0x7C,0x40,0x40,0x78,0x44,0x04,0x04,0x44,0x38,0x00, 6, // 0x36 '6' 0x00,0x38,0x44,0x40,0x40,0x78,0x44,0x44,0x44,0x38,0x00, 6, // 0x37 '7' 0x00,0x7C,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x20,0x00, 6, // 0x38 '8' 0x00,0x38,0x44,0x44,0x44,0x38,0x44,0x44,0x44,0x38,0x00, 6, // 0x39 '9' 0x00,0x38,0x44,0x44,0x44,0x3C,0x04,0x04,0x44,0x38,0x00, 4, // 0x3A ':' 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x60,0x60,0x00, 4, // 0x3B ';' 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x60,0x60,0xC0, 6, // 0x3C '<' 0x00,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x00, 6, // 0x3D '=' 0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x00, 6, // 0x3E '>' 0x00,0x40,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x40,0x00, 6, // 0x3F '?' 0x00,0x38,0x44,0x04,0x04,0x08,0x10,0x10,0x00,0x10,0x00, 6, // 0x40 '@' 0x00,0x38,0x44,0x44,0x5C,0x54,0x54,0x4C,0x40,0x38,0x00, 6, // 0x41 'A' 0x00,0x38,0x44,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x00, 6, // 0x42 'B' 0x00,0x78,0x44,0x44,0x44,0x78,0x44,0x44,0x44,0x78,0x00, 6, // 0x43 'C' 0x00,0x38,0x44,0x40,0x40,0x40,0x40,0x40,0x44,0x38,0x00, 6, // 0x44 'D' 0x00,0x70,0x48,0x44,0x44,0x44,0x44,0x44,0x48,0x70,0x00, 6, // 0x45 'E' 0x00,0x7C,0x40,0x40,0x40,0x78,0x40,0x40,0x40,0x7C,0x00, 6, // 0x46 'F' 0x00,0x7C,0x40,0x40,0x40,0x78,0x40,0x40,0x40,0x40,0x00, 6, // 0x47 'G' 0x00,0x38,0x44,0x40,0x40,0x5C,0x44,0x44,0x4C,0x34,0x00, 6, // 0x48 'H' 0x00,0x44,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0x00, 4, // 0x49 'I' 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00, 6, // 0x4A 'J' 0x00,0x1C,0x08,0x08,0x08,0x08,0x08,0x08,0x48,0x30,0x00, 6, // 0x4B 'K' 0x00,0x44,0x48,0x50,0x60,0x60,0x50,0x48,0x44,0x44,0x00, 6, // 0x4C 'L' 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7C,0x00, 8, // 0x4D 'M' 0x00,0x41,0x63,0x55,0x49,0x49,0x41,0x41,0x41,0x41,0x00, 7, // 0x4E 'N' 0x00,0x42,0x42,0x62,0x52,0x4A,0x46,0x42,0x42,0x42,0x00, 6, // 0x4F 'O' 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00, 6, // 0x50 'P' 0x00,0x78,0x44,0x44,0x44,0x78,0x40,0x40,0x40,0x40,0x00, 6, // 0x51 'Q' 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x54,0x48,0x34,0x00, 6, // 0x52 'R' 0x00,0x78,0x44,0x44,0x44,0x78,0x44,0x44,0x44,0x44,0x00, 6, // 0x53 'S' 0x00,0x38,0x44,0x40,0x40,0x38,0x04,0x04,0x44,0x38,0x00, 6, // 0x54 'T' 0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00, 6, // 0x55 'U' 0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00, 6, // 0x56 'V' 0x00,0x44,0x44,0x44,0x44,0x28,0x28,0x28,0x10,0x10,0x00, 8, // 0x57 'W' 0x00,0x41,0x41,0x41,0x41,0x49,0x49,0x49,0x55,0x22,0x00, 6, // 0x58 'X' 0x00,0x44,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x44,0x00, 6, // 0x59 'Y' 0x00,0x44,0x44,0x44,0x28,0x10,0x10,0x10,0x10,0x10,0x00, 6, // 0x5A 'Z' 0x00,0x7C,0x04,0x04,0x08,0x10,0x20,0x40,0x40,0x7C,0x00, 5, // 0x5B '[' 0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x30, 7, // 0x5C '\' 0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x00, 4, // 0x5D ']' 0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x60, 6, // 0x5E '^' 0x00,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x5F '_' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00, 4, // 0x60 '`' 0x00,0x40,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x61 'a' 0x00,0x00,0x00,0x38,0x04,0x3C,0x44,0x44,0x44,0x3C,0x00, 6, // 0x62 'b' 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x78,0x00, 6, // 0x63 'c' 0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x40,0x44,0x38,0x00, 6, // 0x64 'd' 0x00,0x04,0x04,0x3C,0x44,0x44,0x44,0x44,0x44,0x3C,0x00, 6, // 0x65 'e' 0x00,0x00,0x00,0x38,0x44,0x44,0x7C,0x40,0x44,0x38,0x00, 4, // 0x66 'f' 0x00,0x10,0x20,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x00, 6, // 0x67 'g' 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x3C,0x04,0x44,0x38, 6, // 0x68 'h' 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x44,0x00, 2, // 0x69 'i' 0x00,0x40,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00, 3, // 0x6A 'j' 0x00,0x20,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, 5, // 0x6B 'k' 0x00,0x40,0x40,0x48,0x50,0x60,0x60,0x50,0x48,0x48,0x00, 2, // 0x6C 'l' 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00, 8, // 0x6D 'm' 0x00,0x00,0x00,0x76,0x49,0x49,0x49,0x49,0x41,0x41,0x00, 6, // 0x6E 'n' 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x44,0x44,0x00, 6, // 0x6F 'o' 0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x38,0x00, 6, // 0x70 'p' 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x40,0x40, 6, // 0x71 'q' 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x3C,0x04,0x04, 6, // 0x72 'r' 0x00,0x00,0x00,0x58,0x24,0x20,0x20,0x20,0x20,0x20,0x00, 6, // 0x73 's' 0x00,0x00,0x00,0x38,0x44,0x40,0x38,0x04,0x44,0x38,0x00, 5, // 0x74 't' 0x00,0x20,0x20,0x70,0x20,0x20,0x20,0x20,0x28,0x10,0x00, 6, // 0x75 'u' 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x4C,0x34,0x00, 6, // 0x76 'v' 0x00,0x00,0x00,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x00, 8, // 0x77 'w' 0x00,0x00,0x00,0x41,0x41,0x41,0x41,0x49,0x49,0x36,0x00, 6, // 0x78 'x' 0x00,0x00,0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x00, 6, // 0x79 'y' 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x3C,0x04,0x08,0x70, 6, // 0x7A 'z' 0x00,0x00,0x00,0x7C,0x04,0x08,0x10,0x20,0x40,0x7C,0x00, 5, // 0x7B '{' 0x18,0x20,0x20,0x20,0x20,0xC0,0x20,0x20,0x20,0x20,0x18, 3, // 0x7C '|' 0x00,0x40,0x40,0x40,0x40,0x00,0x40,0x40,0x40,0x40,0x00, 5, // 0x7D '}' 0xC0,0x20,0x20,0x20,0x20,0x18,0x20,0x20,0x20,0x20,0xC0, 6, // 0x7E '~' 0x00,0x24,0x54,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x7F '' 0x00,0x10,0x38,0x6C,0x44,0x44,0x7C,0x00,0x00,0x00,0x00, 0 }; const int8u mcs11_prop_condensed[] = { 11, 2, 32, 128-32, 0x00,0x00,0x0C,0x00,0x18,0x00,0x24,0x00,0x30,0x00,0x3C,0x00,0x48,0x00,0x54,0x00,0x60,0x00, 0x6C,0x00,0x78,0x00,0x84,0x00,0x90,0x00,0x9C,0x00,0xA8,0x00,0xB4,0x00,0xC0,0x00,0xCC,0x00, 0xD8,0x00,0xE4,0x00,0xF0,0x00,0xFC,0x00,0x08,0x01,0x14,0x01,0x20,0x01,0x2C,0x01,0x38,0x01, 0x44,0x01,0x50,0x01,0x5C,0x01,0x68,0x01,0x74,0x01,0x80,0x01,0x8C,0x01,0x98,0x01,0xA4,0x01, 0xB0,0x01,0xBC,0x01,0xC8,0x01,0xD4,0x01,0xE0,0x01,0xEC,0x01,0xF8,0x01,0x04,0x02,0x10,0x02, 0x1C,0x02,0x28,0x02,0x34,0x02,0x40,0x02,0x4C,0x02,0x58,0x02,0x64,0x02,0x70,0x02,0x7C,0x02, 0x88,0x02,0x94,0x02,0xA0,0x02,0xAC,0x02,0xB8,0x02,0xC4,0x02,0xD0,0x02,0xDC,0x02,0xE8,0x02, 0xF4,0x02,0x00,0x03,0x0C,0x03,0x18,0x03,0x24,0x03,0x30,0x03,0x3C,0x03,0x48,0x03,0x54,0x03, 0x60,0x03,0x6C,0x03,0x78,0x03,0x84,0x03,0x90,0x03,0x9C,0x03,0xA8,0x03,0xB4,0x03,0xC0,0x03, 0xCC,0x03,0xD8,0x03,0xE4,0x03,0xF0,0x03,0xFC,0x03,0x08,0x04,0x14,0x04,0x20,0x04,0x2C,0x04, 0x38,0x04,0x44,0x04,0x50,0x04,0x5C,0x04,0x68,0x04,0x74,0x04, 3, // 0x20 ' ' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 3, // 0x21 '!' 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x40,0x00, 4, // 0x22 '"' 0x50,0x50,0xA0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x23 '#' 0x00,0x50,0x50,0xF8,0x50,0x50,0x50,0xF8,0x50,0x50,0x00, 5, // 0x24 '$' 0x00,0x40,0x60,0x90,0x80,0x60,0x10,0x90,0x60,0x20,0x00, 5, // 0x25 '%' 0x00,0x00,0x90,0x90,0x20,0x20,0x40,0x40,0x90,0x90,0x00, 5, // 0x26 '&' 0x00,0x40,0xA0,0xA0,0xA0,0x40,0xA8,0x90,0x90,0x68,0x00, 5, // 0x27 ''' 0x00,0x00,0x20,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x28 '(' 0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x10, 4, // 0x29 ')' 0x80,0x40,0x40,0x20,0x20,0x20,0x20,0x20,0x40,0x40,0x80, 5, // 0x2A '*' 0x00,0x00,0x90,0x60,0xF0,0x60,0x90,0x00,0x00,0x00,0x00, 5, // 0x2B '+' 0x00,0x00,0x00,0x20,0x20,0xF8,0x20,0x20,0x00,0x00,0x00, 4, // 0x2C ',' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0xC0, 5, // 0x2D '-' 0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x00, 4, // 0x2E '.' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0x00, 6, // 0x2F '/' 0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x80,0x00, 5, // 0x30 '0' 0x00,0x70,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0xE0,0x00, 3, // 0x31 '1' 0x00,0x40,0xC0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00, 5, // 0x32 '2' 0x00,0x60,0x90,0x90,0x10,0x10,0x20,0x40,0x80,0xF0,0x00, 5, // 0x33 '3' 0x00,0x60,0x90,0x10,0x10,0x60,0x10,0x10,0x90,0x60,0x00, 5, // 0x34 '4' 0x00,0x10,0x30,0x30,0x50,0x50,0x90,0xF0,0x10,0x10,0x00, 5, // 0x35 '5' 0x00,0xF0,0x80,0x80,0xE0,0x90,0x10,0x10,0x90,0x60,0x00, 5, // 0x36 '6' 0x00,0x60,0x90,0x80,0x80,0xE0,0x90,0x90,0x90,0x60,0x00, 5, // 0x37 '7' 0x00,0xF0,0x10,0x10,0x10,0x20,0x20,0x40,0x40,0x40,0x00, 5, // 0x38 '8' 0x00,0x60,0x90,0x90,0x90,0x60,0x90,0x90,0x90,0x60,0x00, 5, // 0x39 '9' 0x00,0x60,0x90,0x90,0x90,0x70,0x10,0x10,0x90,0x60,0x00, 4, // 0x3A ':' 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x60,0x60,0x00, 4, // 0x3B ';' 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x60,0x60,0xC0, 6, // 0x3C '<' 0x00,0x08,0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x08,0x00, 5, // 0x3D '=' 0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0xF0,0x00,0x00,0x00, 6, // 0x3E '>' 0x00,0x80,0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x80,0x00, 5, // 0x3F '?' 0x00,0x60,0x90,0x10,0x10,0x20,0x40,0x00,0x40,0x00,0x00, 5, // 0x40 '@' 0x00,0x60,0x90,0x90,0xB0,0xB0,0xB0,0x80,0x80,0x70,0x00, 5, // 0x41 'A' 0x00,0x60,0x90,0x90,0x90,0xF0,0x90,0x90,0x90,0x90,0x00, 5, // 0x42 'B' 0x00,0xE0,0x90,0x90,0x90,0xE0,0x90,0x90,0x90,0xE0,0x00, 5, // 0x43 'C' 0x00,0x60,0x90,0x80,0x80,0x80,0x80,0x80,0x90,0x60,0x00, 5, // 0x44 'D' 0x00,0xE0,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0xE0,0x00, 5, // 0x45 'E' 0x00,0xF0,0x80,0x80,0x80,0xF0,0x80,0x80,0x80,0xF0,0x00, 5, // 0x46 'F' 0x00,0xF0,0x80,0x80,0x80,0xF0,0x80,0x80,0x80,0x80,0x00, 5, // 0x47 'G' 0x00,0x70,0x80,0x80,0x80,0xB0,0x90,0x90,0x90,0x60,0x00, 5, // 0x48 'H' 0x00,0x90,0x90,0x90,0x90,0xF0,0x90,0x90,0x90,0x90,0x00, 4, // 0x49 'I' 0x00,0xE0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xE0,0x00, 5, // 0x4A 'J' 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0xA0,0xA0,0x40,0x00, 5, // 0x4B 'K' 0x00,0x90,0x90,0xA0,0xA0,0xC0,0xA0,0xA0,0x90,0x90,0x00, 5, // 0x4C 'L' 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xF0,0x00, 6, // 0x4D 'M' 0x00,0x88,0xD8,0xA8,0xA8,0xA8,0x88,0x88,0x88,0x88,0x00, 5, // 0x4E 'N' 0x00,0x90,0x90,0xD0,0xD0,0xB0,0xB0,0x90,0x90,0x90,0x00, 5, // 0x4F 'O' 0x00,0x60,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x60,0x00, 5, // 0x50 'P' 0x00,0xE0,0x90,0x90,0x90,0x90,0xE0,0x80,0x80,0x80,0x00, 5, // 0x51 'Q' 0x00,0x60,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x60,0x30, 5, // 0x52 'R' 0x00,0xE0,0x90,0x90,0x90,0x90,0xE0,0xA0,0x90,0x90,0x00, 5, // 0x53 'S' 0x00,0x60,0x90,0x80,0x80,0x60,0x10,0x10,0x90,0x60,0x00, 6, // 0x54 'T' 0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00, 5, // 0x55 'U' 0x00,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x60,0x00, 6, // 0x56 'V' 0x00,0x88,0x88,0x88,0x88,0x50,0x50,0x50,0x20,0x20,0x00, 6, // 0x57 'W' 0x00,0x88,0x88,0x88,0xA8,0xA8,0xA8,0xA8,0xA8,0x50,0x00, 5, // 0x58 'X' 0x00,0x90,0x90,0x90,0x60,0x60,0x90,0x90,0x90,0x90,0x00, 6, // 0x59 'Y' 0x00,0x88,0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x20,0x00, 5, // 0x5A 'Z' 0x00,0xF0,0x10,0x20,0x20,0x40,0x40,0x80,0x80,0xF0,0x00, 4, // 0x5B '[' 0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x60,0x00, 6, // 0x5C '\' 0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x00, 4, // 0x5D ']' 0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x60,0x00, 5, // 0x5E '^' 0x00,0x20,0x50,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x5F '_' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00, 5, // 0x60 '`' 0x00,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x61 'a' 0x00,0x00,0x00,0x60,0x90,0x10,0x70,0x90,0x90,0x70,0x00, 5, // 0x62 'b' 0x00,0x80,0x80,0x80,0xE0,0x90,0x90,0x90,0x90,0xE0,0x00, 5, // 0x63 'c' 0x00,0x00,0x00,0x60,0x90,0x80,0x80,0x80,0x90,0x60,0x00, 5, // 0x64 'd' 0x00,0x10,0x10,0x10,0x70,0x90,0x90,0x90,0x90,0x70,0x00, 5, // 0x65 'e' 0x00,0x00,0x00,0x60,0x90,0x90,0xF0,0x80,0x90,0x60,0x00, 4, // 0x66 'f' 0x00,0x20,0x40,0x40,0xE0,0x40,0x40,0x40,0x40,0x40,0x00, 5, // 0x67 'g' 0x00,0x00,0x00,0x70,0x90,0x90,0x90,0x70,0x10,0x90,0x60, 5, // 0x68 'h' 0x00,0x80,0x80,0x80,0xE0,0x90,0x90,0x90,0x90,0x90,0x00, 2, // 0x69 'i' 0x00,0x80,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00, 4, // 0x6A 'j' 0x00,0x20,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, 5, // 0x6B 'k' 0x00,0x80,0x80,0x90,0x90,0xA0,0xC0,0xA0,0x90,0x90,0x00, 2, // 0x6C 'l' 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00, 6, // 0x6D 'm' 0x00,0x00,0x00,0xD0,0xA8,0xA8,0xA8,0x88,0x88,0x88,0x00, 5, // 0x6E 'n' 0x00,0x00,0x00,0xA0,0xD0,0x90,0x90,0x90,0x90,0x90,0x00, 5, // 0x6F 'o' 0x00,0x00,0x00,0x60,0x90,0x90,0x90,0x90,0x90,0x60,0x00, 5, // 0x70 'p' 0x00,0x00,0x00,0xE0,0x90,0x90,0x90,0x90,0xE0,0x80,0x80, 5, // 0x71 'q' 0x00,0x00,0x00,0x70,0x90,0x90,0x90,0x90,0x70,0x10,0x10, 6, // 0x72 'r' 0x00,0x00,0x00,0xB8,0x48,0x40,0x40,0x40,0x40,0x40,0x00, 5, // 0x73 's' 0x00,0x00,0x00,0x60,0x90,0x40,0x20,0x10,0x90,0x60,0x00, 4, // 0x74 't' 0x00,0x40,0x40,0xE0,0x40,0x40,0x40,0x40,0x40,0x20,0x00, 5, // 0x75 'u' 0x00,0x00,0x00,0x90,0x90,0x90,0x90,0x90,0x90,0x70,0x00, 6, // 0x76 'v' 0x00,0x00,0x00,0x88,0x88,0x88,0x50,0x50,0x20,0x20,0x00, 6, // 0x77 'w' 0x00,0x00,0x00,0x88,0x88,0x88,0xA8,0xA8,0xA8,0x50,0x00, 5, // 0x78 'x' 0x00,0x00,0x00,0x90,0x90,0x60,0x60,0x90,0x90,0x90,0x00, 5, // 0x79 'y' 0x00,0x00,0x00,0x90,0x90,0x90,0x90,0x70,0x10,0x20,0xC0, 5, // 0x7A 'z' 0x00,0x00,0x00,0xF0,0x10,0x20,0x40,0x80,0x80,0xF0,0x00, 5, // 0x7B '{' 0x30,0x40,0x40,0x40,0x40,0x80,0x40,0x40,0x40,0x40,0x30, 3, // 0x7C '|' 0x00,0x40,0x40,0x40,0x40,0x00,0x40,0x40,0x40,0x40,0x00, 5, // 0x7D '}' 0xC0,0x20,0x20,0x20,0x20,0x10,0x20,0x20,0x20,0x20,0xC0, 5, // 0x7E '~' 0x00,0x40,0xA8,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x7F '' 0x00,0x20,0x70,0xD8,0x88,0x88,0xF8,0x00,0x00,0x00,0x00, 0 }; const int8u mcs12_prop[] = { 12, 3, 32, 128-32, 0x00,0x00,0x0D,0x00,0x1A,0x00,0x27,0x00,0x34,0x00,0x41,0x00,0x4E,0x00,0x5B,0x00,0x68,0x00, 0x75,0x00,0x82,0x00,0x8F,0x00,0x9C,0x00,0xA9,0x00,0xB6,0x00,0xC3,0x00,0xD0,0x00,0xDD,0x00, 0xEA,0x00,0xF7,0x00,0x04,0x01,0x11,0x01,0x1E,0x01,0x2B,0x01,0x38,0x01,0x45,0x01,0x52,0x01, 0x5F,0x01,0x6C,0x01,0x79,0x01,0x86,0x01,0x93,0x01,0xA0,0x01,0xAD,0x01,0xBA,0x01,0xC7,0x01, 0xD4,0x01,0xE1,0x01,0xEE,0x01,0xFB,0x01,0x08,0x02,0x15,0x02,0x22,0x02,0x2F,0x02,0x3C,0x02, 0x49,0x02,0x62,0x02,0x6F,0x02,0x7C,0x02,0x89,0x02,0x96,0x02,0xA3,0x02,0xB0,0x02,0xBD,0x02, 0xCA,0x02,0xD7,0x02,0xF0,0x02,0xFD,0x02,0x0A,0x03,0x17,0x03,0x24,0x03,0x31,0x03,0x3E,0x03, 0x4B,0x03,0x58,0x03,0x65,0x03,0x72,0x03,0x7F,0x03,0x8C,0x03,0x99,0x03,0xA6,0x03,0xB3,0x03, 0xC0,0x03,0xCD,0x03,0xDA,0x03,0xE7,0x03,0xF4,0x03,0x01,0x04,0x1A,0x04,0x27,0x04,0x34,0x04, 0x41,0x04,0x4E,0x04,0x5B,0x04,0x68,0x04,0x75,0x04,0x82,0x04,0x8F,0x04,0xA8,0x04,0xB5,0x04, 0xC2,0x04,0xCF,0x04,0xDC,0x04,0xE9,0x04,0xF6,0x04,0x03,0x05, 5, // 0x20 ' ' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 4, // 0x21 '!' 0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00, 4, // 0x22 '"' 0x50,0x50,0xA0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x23 '#' 0x28,0x28,0x28,0x7C,0x28,0x28,0x28,0x7C,0x28,0x28,0x28,0x00, 6, // 0x24 '$' 0x10,0x10,0x38,0x54,0x50,0x38,0x14,0x54,0x38,0x10,0x10,0x00, 7, // 0x25 '%' 0x32,0x54,0x64,0x08,0x08,0x10,0x10,0x26,0x2A,0x4C,0x00,0x00, 7, // 0x26 '&' 0x00,0x30,0x48,0x48,0x48,0x30,0x4A,0x4A,0x44,0x3A,0x00,0x00, 3, // 0x27 ''' 0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x28 '(' 0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x10,0x00, 5, // 0x29 ')' 0x40,0x20,0x20,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x40,0x00, 6, // 0x2A '*' 0x00,0x00,0x10,0x54,0x38,0x7C,0x38,0x54,0x10,0x00,0x00,0x00, 6, // 0x2B '+' 0x00,0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00,0x00, 4, // 0x2C ',' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x40,0x80, 6, // 0x2D '-' 0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00, 4, // 0x2E '.' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00, 7, // 0x2F '/' 0x00,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x00, 7, // 0x30 '0' 0x00,0x38,0x44,0x44,0x54,0x54,0x54,0x44,0x44,0x38,0x00,0x00, 4, // 0x31 '1' 0x00,0x20,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00, 7, // 0x32 '2' 0x00,0x38,0x44,0x04,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,0x00, 7, // 0x33 '3' 0x00,0x38,0x44,0x04,0x04,0x38,0x04,0x04,0x44,0x38,0x00,0x00, 6, // 0x34 '4' 0x00,0x08,0x18,0x28,0x28,0x48,0x48,0x7C,0x08,0x08,0x00,0x00, 7, // 0x35 '5' 0x00,0x7C,0x40,0x40,0x78,0x44,0x04,0x04,0x44,0x38,0x00,0x00, 7, // 0x36 '6' 0x00,0x38,0x44,0x40,0x78,0x44,0x44,0x44,0x44,0x38,0x00,0x00, 6, // 0x37 '7' 0x00,0x7C,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x20,0x00,0x00, 7, // 0x38 '8' 0x00,0x38,0x44,0x44,0x44,0x38,0x44,0x44,0x44,0x38,0x00,0x00, 7, // 0x39 '9' 0x00,0x38,0x44,0x44,0x44,0x3C,0x04,0x04,0x44,0x38,0x00,0x00, 4, // 0x3A ':' 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x60,0x60,0x00,0x00, 4, // 0x3B ';' 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x60,0x60,0x40,0x80, 6, // 0x3C '<' 0x00,0x00,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x00, 6, // 0x3D '=' 0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x00,0x00, 6, // 0x3E '>' 0x00,0x00,0x40,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x40,0x00, 6, // 0x3F '?' 0x00,0x38,0x44,0x04,0x04,0x08,0x10,0x10,0x00,0x10,0x00,0x00, 7, // 0x40 '@' 0x00,0x38,0x44,0x44,0x5C,0x54,0x54,0x4C,0x40,0x38,0x00,0x00, 7, // 0x41 'A' 0x00,0x38,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0x00,0x00, 7, // 0x42 'B' 0x00,0x78,0x44,0x44,0x44,0x78,0x44,0x44,0x44,0x78,0x00,0x00, 6, // 0x43 'C' 0x00,0x38,0x44,0x40,0x40,0x40,0x40,0x40,0x44,0x38,0x00,0x00, 7, // 0x44 'D' 0x00,0x70,0x48,0x44,0x44,0x44,0x44,0x44,0x48,0x70,0x00,0x00, 6, // 0x45 'E' 0x00,0x7C,0x40,0x40,0x40,0x78,0x40,0x40,0x40,0x7C,0x00,0x00, 6, // 0x46 'F' 0x00,0x7C,0x40,0x40,0x40,0x78,0x40,0x40,0x40,0x40,0x00,0x00, 7, // 0x47 'G' 0x00,0x38,0x44,0x40,0x40,0x5C,0x44,0x44,0x4C,0x34,0x00,0x00, 7, // 0x48 'H' 0x00,0x44,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0x00,0x00, 5, // 0x49 'I' 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, 6, // 0x4A 'J' 0x00,0x1C,0x08,0x08,0x08,0x08,0x08,0x48,0x48,0x30,0x00,0x00, 6, // 0x4B 'K' 0x00,0x44,0x48,0x50,0x60,0x60,0x50,0x48,0x44,0x44,0x00,0x00, 6, // 0x4C 'L' 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7C,0x00,0x00, 9, // 0x4D 'M' 0x00,0x00,0x41,0x00,0x63,0x00,0x55,0x00,0x49,0x00,0x49,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00, 7, // 0x4E 'N' 0x00,0x44,0x64,0x64,0x54,0x54,0x4C,0x4C,0x44,0x44,0x00,0x00, 7, // 0x4F 'O' 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, 7, // 0x50 'P' 0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x40,0x40,0x40,0x00,0x00, 7, // 0x51 'Q' 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x54,0x48,0x34,0x00,0x00, 7, // 0x52 'R' 0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x48,0x44,0x44,0x00,0x00, 7, // 0x53 'S' 0x00,0x38,0x44,0x40,0x40,0x38,0x04,0x04,0x44,0x38,0x00,0x00, 6, // 0x54 'T' 0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, 7, // 0x55 'U' 0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, 6, // 0x56 'V' 0x00,0x44,0x44,0x44,0x44,0x28,0x28,0x28,0x10,0x10,0x00,0x00, 9, // 0x57 'W' 0x00,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x49,0x00,0x49,0x00,0x55,0x00,0x22,0x00,0x00,0x00,0x00,0x00, 7, // 0x58 'X' 0x00,0x44,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x44,0x00,0x00, 7, // 0x59 'Y' 0x00,0x44,0x44,0x44,0x44,0x28,0x10,0x10,0x10,0x10,0x00,0x00, 6, // 0x5A 'Z' 0x00,0x7C,0x04,0x04,0x08,0x10,0x20,0x40,0x40,0x7C,0x00,0x00, 4, // 0x5B '[' 0x70,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x70,0x00, 7, // 0x5C '\' 0x00,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x00, 4, // 0x5D ']' 0xE0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xE0,0x00, 6, // 0x5E '^' 0x00,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x5F '_' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00, 4, // 0x60 '`' 0x00,0x40,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x61 'a' 0x00,0x00,0x00,0x38,0x04,0x3C,0x44,0x44,0x44,0x3C,0x00,0x00, 7, // 0x62 'b' 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x78,0x00,0x00, 6, // 0x63 'c' 0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x40,0x44,0x38,0x00,0x00, 7, // 0x64 'd' 0x00,0x04,0x04,0x3C,0x44,0x44,0x44,0x44,0x44,0x3C,0x00,0x00, 7, // 0x65 'e' 0x00,0x00,0x00,0x38,0x44,0x44,0x7C,0x40,0x44,0x38,0x00,0x00, 4, // 0x66 'f' 0x00,0x30,0x40,0xE0,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00, 7, // 0x67 'g' 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x44,0x3C,0x04,0x78, 7, // 0x68 'h' 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x44,0x00,0x00, 3, // 0x69 'i' 0x00,0x40,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00, 5, // 0x6A 'j' 0x00,0x10,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x90,0x60, 6, // 0x6B 'k' 0x00,0x40,0x40,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x00,0x00, 3, // 0x6C 'l' 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00, 9, // 0x6D 'm' 0x00,0x00,0x00,0x00,0x00,0x00,0x76,0x00,0x49,0x00,0x49,0x00,0x49,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00, 7, // 0x6E 'n' 0x00,0x00,0x00,0x58,0x64,0x44,0x44,0x44,0x44,0x44,0x00,0x00, 7, // 0x6F 'o' 0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, 7, // 0x70 'p' 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x44,0x78,0x40,0x40, 7, // 0x71 'q' 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x44,0x3C,0x04,0x04, 6, // 0x72 'r' 0x00,0x00,0x00,0x58,0x24,0x20,0x20,0x20,0x20,0x70,0x00,0x00, 7, // 0x73 's' 0x00,0x00,0x00,0x38,0x44,0x40,0x38,0x04,0x44,0x38,0x00,0x00, 5, // 0x74 't' 0x00,0x20,0x20,0x70,0x20,0x20,0x20,0x20,0x20,0x18,0x00,0x00, 7, // 0x75 'u' 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x4C,0x34,0x00,0x00, 6, // 0x76 'v' 0x00,0x00,0x00,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x00,0x00, 9, // 0x77 'w' 0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x49,0x00,0x49,0x00,0x49,0x00,0x36,0x00,0x00,0x00,0x00,0x00, 7, // 0x78 'x' 0x00,0x00,0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x00,0x00, 7, // 0x79 'y' 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x3C,0x08,0x70, 6, // 0x7A 'z' 0x00,0x00,0x00,0x7C,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,0x00, 5, // 0x7B '{' 0x18,0x20,0x20,0x20,0x20,0xC0,0x20,0x20,0x20,0x20,0x18,0x00, 3, // 0x7C '|' 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00, 5, // 0x7D '}' 0xC0,0x20,0x20,0x20,0x20,0x18,0x20,0x20,0x20,0x20,0xC0,0x00, 7, // 0x7E '~' 0x00,0x60,0x92,0x92,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x7F '' 0x00,0x10,0x38,0x6C,0x44,0x44,0x7C,0x00,0x00,0x00,0x00,0x00, 0 }; const int8u mcs13_prop[] = { 13, 4, 32, 128-32, 0x00,0x00,0x0E,0x00,0x1C,0x00,0x2A,0x00,0x38,0x00,0x46,0x00,0x54,0x00,0x62,0x00,0x70,0x00, 0x7E,0x00,0x8C,0x00,0x9A,0x00,0xA8,0x00,0xB6,0x00,0xC4,0x00,0xD2,0x00,0xE0,0x00,0xEE,0x00, 0xFC,0x00,0x0A,0x01,0x18,0x01,0x26,0x01,0x34,0x01,0x42,0x01,0x50,0x01,0x5E,0x01,0x6C,0x01, 0x7A,0x01,0x88,0x01,0x96,0x01,0xA4,0x01,0xB2,0x01,0xC0,0x01,0xCE,0x01,0xDC,0x01,0xEA,0x01, 0xF8,0x01,0x06,0x02,0x14,0x02,0x22,0x02,0x30,0x02,0x3E,0x02,0x4C,0x02,0x5A,0x02,0x68,0x02, 0x76,0x02,0x91,0x02,0x9F,0x02,0xAD,0x02,0xBB,0x02,0xC9,0x02,0xD7,0x02,0xE5,0x02,0xF3,0x02, 0x01,0x03,0x0F,0x03,0x2A,0x03,0x38,0x03,0x46,0x03,0x54,0x03,0x62,0x03,0x70,0x03,0x7E,0x03, 0x8C,0x03,0x9A,0x03,0xA8,0x03,0xB6,0x03,0xC4,0x03,0xD2,0x03,0xE0,0x03,0xEE,0x03,0xFC,0x03, 0x0A,0x04,0x18,0x04,0x26,0x04,0x34,0x04,0x42,0x04,0x50,0x04,0x6B,0x04,0x79,0x04,0x87,0x04, 0x95,0x04,0xA3,0x04,0xB1,0x04,0xBF,0x04,0xCD,0x04,0xDB,0x04,0xE9,0x04,0x04,0x05,0x12,0x05, 0x20,0x05,0x2E,0x05,0x3C,0x05,0x4A,0x05,0x58,0x05,0x66,0x05, 5, // 0x20 ' ' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 4, // 0x21 '!' 0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00, 4, // 0x22 '"' 0x00,0x50,0x50,0xA0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x23 '#' 0x00,0x28,0x28,0x28,0x7C,0x28,0x28,0x28,0x7C,0x28,0x28,0x28,0x00, 6, // 0x24 '$' 0x00,0x10,0x10,0x38,0x54,0x50,0x38,0x14,0x54,0x38,0x10,0x10,0x00, 7, // 0x25 '%' 0x00,0x32,0x54,0x64,0x08,0x08,0x10,0x10,0x26,0x2A,0x4C,0x00,0x00, 7, // 0x26 '&' 0x00,0x30,0x48,0x48,0x48,0x30,0x4A,0x4A,0x44,0x3A,0x00,0x00,0x00, 3, // 0x27 ''' 0x00,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x28 '(' 0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x10,0x00,0x00, 5, // 0x29 ')' 0x40,0x20,0x20,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x40,0x00,0x00, 6, // 0x2A '*' 0x00,0x00,0x10,0x54,0x38,0x7C,0x38,0x54,0x10,0x00,0x00,0x00,0x00, 6, // 0x2B '+' 0x00,0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00,0x00,0x00, 4, // 0x2C ',' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x20,0x40,0x80, 6, // 0x2D '-' 0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00, 4, // 0x2E '.' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00, 7, // 0x2F '/' 0x00,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x00,0x00, 7, // 0x30 '0' 0x00,0x38,0x44,0x44,0x54,0x54,0x54,0x44,0x44,0x38,0x00,0x00,0x00, 4, // 0x31 '1' 0x00,0x20,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00, 7, // 0x32 '2' 0x00,0x38,0x44,0x04,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,0x00,0x00, 7, // 0x33 '3' 0x00,0x38,0x44,0x04,0x04,0x38,0x04,0x04,0x44,0x38,0x00,0x00,0x00, 6, // 0x34 '4' 0x00,0x08,0x18,0x28,0x28,0x48,0x48,0x7C,0x08,0x08,0x00,0x00,0x00, 7, // 0x35 '5' 0x00,0x7C,0x40,0x40,0x78,0x44,0x04,0x04,0x44,0x38,0x00,0x00,0x00, 7, // 0x36 '6' 0x00,0x38,0x44,0x40,0x78,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, 6, // 0x37 '7' 0x00,0x7C,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x20,0x00,0x00,0x00, 7, // 0x38 '8' 0x00,0x38,0x44,0x44,0x44,0x38,0x44,0x44,0x44,0x38,0x00,0x00,0x00, 7, // 0x39 '9' 0x00,0x38,0x44,0x44,0x44,0x3C,0x04,0x04,0x44,0x38,0x00,0x00,0x00, 4, // 0x3A ':' 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00, 4, // 0x3B ';' 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x60,0x60,0x20,0x40,0x80, 6, // 0x3C '<' 0x00,0x00,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x00,0x00, 6, // 0x3D '=' 0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00, 6, // 0x3E '>' 0x00,0x00,0x40,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x40,0x00,0x00, 6, // 0x3F '?' 0x00,0x38,0x44,0x04,0x04,0x08,0x10,0x10,0x00,0x10,0x00,0x00,0x00, 7, // 0x40 '@' 0x00,0x38,0x44,0x44,0x5C,0x54,0x54,0x4C,0x40,0x38,0x00,0x00,0x00, 7, // 0x41 'A' 0x00,0x38,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0x00,0x00,0x00, 7, // 0x42 'B' 0x00,0x78,0x44,0x44,0x44,0x78,0x44,0x44,0x44,0x78,0x00,0x00,0x00, 6, // 0x43 'C' 0x00,0x38,0x44,0x40,0x40,0x40,0x40,0x40,0x44,0x38,0x00,0x00,0x00, 7, // 0x44 'D' 0x00,0x70,0x48,0x44,0x44,0x44,0x44,0x44,0x48,0x70,0x00,0x00,0x00, 6, // 0x45 'E' 0x00,0x7C,0x40,0x40,0x40,0x78,0x40,0x40,0x40,0x7C,0x00,0x00,0x00, 6, // 0x46 'F' 0x00,0x7C,0x40,0x40,0x40,0x78,0x40,0x40,0x40,0x40,0x00,0x00,0x00, 7, // 0x47 'G' 0x00,0x38,0x44,0x40,0x40,0x5C,0x44,0x44,0x4C,0x34,0x00,0x00,0x00, 7, // 0x48 'H' 0x00,0x44,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0x00,0x00,0x00, 5, // 0x49 'I' 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00,0x00, 6, // 0x4A 'J' 0x00,0x1C,0x08,0x08,0x08,0x08,0x08,0x48,0x48,0x30,0x00,0x00,0x00, 6, // 0x4B 'K' 0x00,0x44,0x48,0x50,0x60,0x60,0x50,0x48,0x44,0x44,0x00,0x00,0x00, 6, // 0x4C 'L' 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7C,0x00,0x00,0x00, 9, // 0x4D 'M' 0x00,0x00,0x41,0x00,0x63,0x00,0x55,0x00,0x49,0x00,0x49,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x4E 'N' 0x00,0x44,0x64,0x64,0x54,0x54,0x4C,0x4C,0x44,0x44,0x00,0x00,0x00, 7, // 0x4F 'O' 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, 7, // 0x50 'P' 0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x40,0x40,0x40,0x00,0x00,0x00, 7, // 0x51 'Q' 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x54,0x48,0x34,0x00,0x00,0x00, 7, // 0x52 'R' 0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x48,0x44,0x44,0x00,0x00,0x00, 7, // 0x53 'S' 0x00,0x38,0x44,0x40,0x40,0x38,0x04,0x04,0x44,0x38,0x00,0x00,0x00, 6, // 0x54 'T' 0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00, 7, // 0x55 'U' 0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, 6, // 0x56 'V' 0x00,0x44,0x44,0x44,0x44,0x28,0x28,0x28,0x10,0x10,0x00,0x00,0x00, 9, // 0x57 'W' 0x00,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x49,0x00,0x49,0x00,0x55,0x00,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x58 'X' 0x00,0x44,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x44,0x00,0x00,0x00, 7, // 0x59 'Y' 0x00,0x44,0x44,0x44,0x44,0x28,0x10,0x10,0x10,0x10,0x00,0x00,0x00, 6, // 0x5A 'Z' 0x00,0x7C,0x04,0x04,0x08,0x10,0x20,0x40,0x40,0x7C,0x00,0x00,0x00, 4, // 0x5B '[' 0x70,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x70,0x00,0x00, 7, // 0x5C '\' 0x00,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x00,0x00, 4, // 0x5D ']' 0xE0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xE0,0x00,0x00, 6, // 0x5E '^' 0x00,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x5F '_' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00, 4, // 0x60 '`' 0x00,0x40,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x61 'a' 0x00,0x00,0x00,0x38,0x04,0x3C,0x44,0x44,0x44,0x3C,0x00,0x00,0x00, 7, // 0x62 'b' 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x78,0x00,0x00,0x00, 6, // 0x63 'c' 0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x40,0x44,0x38,0x00,0x00,0x00, 7, // 0x64 'd' 0x00,0x04,0x04,0x3C,0x44,0x44,0x44,0x44,0x44,0x3C,0x00,0x00,0x00, 7, // 0x65 'e' 0x00,0x00,0x00,0x38,0x44,0x44,0x7C,0x40,0x44,0x38,0x00,0x00,0x00, 4, // 0x66 'f' 0x00,0x30,0x40,0xE0,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, 7, // 0x67 'g' 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x44,0x3C,0x04,0x44,0x38, 7, // 0x68 'h' 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x44,0x00,0x00,0x00, 3, // 0x69 'i' 0x00,0x40,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, 5, // 0x6A 'j' 0x00,0x10,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x90,0x60,0x00, 6, // 0x6B 'k' 0x00,0x40,0x40,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x00,0x00,0x00, 3, // 0x6C 'l' 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, 9, // 0x6D 'm' 0x00,0x00,0x00,0x00,0x00,0x00,0x76,0x00,0x49,0x00,0x49,0x00,0x49,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x6E 'n' 0x00,0x00,0x00,0x58,0x64,0x44,0x44,0x44,0x44,0x44,0x00,0x00,0x00, 7, // 0x6F 'o' 0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, 7, // 0x70 'p' 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x44,0x78,0x40,0x40,0x40, 7, // 0x71 'q' 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x44,0x3C,0x04,0x04,0x04, 6, // 0x72 'r' 0x00,0x00,0x00,0x58,0x24,0x20,0x20,0x20,0x20,0x70,0x00,0x00,0x00, 7, // 0x73 's' 0x00,0x00,0x00,0x38,0x44,0x40,0x38,0x04,0x44,0x38,0x00,0x00,0x00, 5, // 0x74 't' 0x00,0x20,0x20,0x70,0x20,0x20,0x20,0x20,0x20,0x18,0x00,0x00,0x00, 7, // 0x75 'u' 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x4C,0x34,0x00,0x00,0x00, 6, // 0x76 'v' 0x00,0x00,0x00,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x00,0x00,0x00, 9, // 0x77 'w' 0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x49,0x00,0x49,0x00,0x49,0x00,0x36,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x78 'x' 0x00,0x00,0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x00,0x00,0x00, 7, // 0x79 'y' 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x3C,0x04,0x08,0x70, 6, // 0x7A 'z' 0x00,0x00,0x00,0x7C,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,0x00,0x00, 5, // 0x7B '{' 0x18,0x20,0x20,0x20,0x20,0xC0,0x20,0x20,0x20,0x20,0x18,0x00,0x00, 3, // 0x7C '|' 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00, 5, // 0x7D '}' 0xC0,0x20,0x20,0x20,0x20,0x18,0x20,0x20,0x20,0x20,0xC0,0x00,0x00, 7, // 0x7E '~' 0x00,0x60,0x92,0x92,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x7F '' 0x00,0x10,0x38,0x6C,0x44,0x44,0x7C,0x00,0x00,0x00,0x00,0x00,0x00, 0 }; const int8u mcs5x10_mono[] = { 10, 2, 32, 128-32, 0x00,0x00,0x0B,0x00,0x16,0x00,0x21,0x00,0x2C,0x00,0x37,0x00,0x42,0x00,0x4D,0x00,0x58,0x00, 0x63,0x00,0x6E,0x00,0x79,0x00,0x84,0x00,0x8F,0x00,0x9A,0x00,0xA5,0x00,0xB0,0x00,0xBB,0x00, 0xC6,0x00,0xD1,0x00,0xDC,0x00,0xE7,0x00,0xF2,0x00,0xFD,0x00,0x08,0x01,0x13,0x01,0x1E,0x01, 0x29,0x01,0x34,0x01,0x3F,0x01,0x4A,0x01,0x55,0x01,0x60,0x01,0x6B,0x01,0x76,0x01,0x81,0x01, 0x8C,0x01,0x97,0x01,0xA2,0x01,0xAD,0x01,0xB8,0x01,0xC3,0x01,0xCE,0x01,0xD9,0x01,0xE4,0x01, 0xEF,0x01,0xFA,0x01,0x05,0x02,0x10,0x02,0x1B,0x02,0x26,0x02,0x31,0x02,0x3C,0x02,0x47,0x02, 0x52,0x02,0x5D,0x02,0x68,0x02,0x73,0x02,0x7E,0x02,0x89,0x02,0x94,0x02,0x9F,0x02,0xAA,0x02, 0xB5,0x02,0xC0,0x02,0xCB,0x02,0xD6,0x02,0xE1,0x02,0xEC,0x02,0xF7,0x02,0x02,0x03,0x0D,0x03, 0x18,0x03,0x23,0x03,0x2E,0x03,0x39,0x03,0x44,0x03,0x4F,0x03,0x5A,0x03,0x65,0x03,0x70,0x03, 0x7B,0x03,0x86,0x03,0x91,0x03,0x9C,0x03,0xA7,0x03,0xB2,0x03,0xBD,0x03,0xC8,0x03,0xD3,0x03, 0xDE,0x03,0xE9,0x03,0xF4,0x03,0xFF,0x03,0x0A,0x04,0x15,0x04, 5, // 0x20 ' ' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x21 '!' 0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00, 5, // 0x22 '"' 0x00,0x50,0x50,0xA0,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x23 '#' 0x00,0x50,0x50,0xF8,0x50,0x50,0x50,0xF8,0x50,0x50, 5, // 0x24 '$' 0x00,0x40,0x60,0x90,0x80,0x60,0x10,0x90,0x60,0x20, 5, // 0x25 '%' 0x00,0x00,0x90,0x90,0x20,0x20,0x40,0x40,0x90,0x90, 5, // 0x26 '&' 0x00,0x40,0xA0,0xA0,0xA0,0x40,0xA8,0x90,0x90,0x68, 5, // 0x27 ''' 0x00,0x20,0x20,0x40,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x28 '(' 0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x20,0x20,0x10, 5, // 0x29 ')' 0x40,0x20,0x20,0x10,0x10,0x10,0x10,0x20,0x20,0x40, 5, // 0x2A '*' 0x00,0x00,0x90,0x60,0xF0,0x60,0x90,0x00,0x00,0x00, 5, // 0x2B '+' 0x00,0x00,0x00,0x20,0x20,0xF8,0x20,0x20,0x00,0x00, 5, // 0x2C ',' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0xC0, 5, // 0x2D '-' 0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00, 5, // 0x2E '.' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00, 5, // 0x2F '/' 0x00,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x00, 5, // 0x30 '0' 0x00,0x70,0x90,0x90,0x90,0x90,0x90,0x90,0xE0,0x00, 5, // 0x31 '1' 0x00,0x20,0x60,0x20,0x20,0x20,0x20,0x20,0x70,0x00, 5, // 0x32 '2' 0x00,0x60,0x90,0x90,0x10,0x20,0x40,0x80,0xF0,0x00, 5, // 0x33 '3' 0x00,0x60,0x90,0x10,0x60,0x10,0x10,0x90,0x60,0x00, 5, // 0x34 '4' 0x00,0x10,0x30,0x50,0x50,0x90,0xF0,0x10,0x10,0x00, 5, // 0x35 '5' 0x00,0xF0,0x80,0x80,0xE0,0x10,0x10,0x90,0x60,0x00, 5, // 0x36 '6' 0x00,0x60,0x80,0x80,0xE0,0x90,0x90,0x90,0x60,0x00, 5, // 0x37 '7' 0x00,0xF0,0x10,0x10,0x20,0x20,0x40,0x40,0x40,0x00, 5, // 0x38 '8' 0x00,0x60,0x90,0x90,0x60,0x90,0x90,0x90,0x60,0x00, 5, // 0x39 '9' 0x00,0x60,0x90,0x90,0x90,0x70,0x10,0x10,0x60,0x00, 5, // 0x3A ':' 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x60,0x60,0x00, 5, // 0x3B ';' 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x60,0x60,0xC0, 5, // 0x3C '<' 0x00,0x08,0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x08, 5, // 0x3D '=' 0x00,0x00,0x00,0x00,0xF0,0x00,0xF0,0x00,0x00,0x00, 5, // 0x3E '>' 0x00,0x80,0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x80, 5, // 0x3F '?' 0x00,0x60,0x90,0x10,0x10,0x20,0x40,0x00,0x40,0x00, 5, // 0x40 '@' 0x00,0x60,0x90,0x90,0xB0,0xB0,0x80,0x80,0x70,0x00, 5, // 0x41 'A' 0x00,0x60,0x90,0x90,0x90,0xF0,0x90,0x90,0x90,0x00, 5, // 0x42 'B' 0x00,0xE0,0x90,0x90,0xE0,0x90,0x90,0x90,0xE0,0x00, 5, // 0x43 'C' 0x00,0x60,0x90,0x80,0x80,0x80,0x80,0x90,0x60,0x00, 5, // 0x44 'D' 0x00,0xE0,0x90,0x90,0x90,0x90,0x90,0x90,0xE0,0x00, 5, // 0x45 'E' 0x00,0xF0,0x80,0x80,0xF0,0x80,0x80,0x80,0xF0,0x00, 5, // 0x46 'F' 0x00,0xF0,0x80,0x80,0xF0,0x80,0x80,0x80,0x80,0x00, 5, // 0x47 'G' 0x00,0x60,0x90,0x80,0x80,0xB0,0x90,0x90,0x60,0x00, 5, // 0x48 'H' 0x00,0x90,0x90,0x90,0x90,0xF0,0x90,0x90,0x90,0x00, 5, // 0x49 'I' 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00, 5, // 0x4A 'J' 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0xA0,0x40,0x00, 5, // 0x4B 'K' 0x00,0x90,0xA0,0xA0,0xC0,0xC0,0xA0,0xA0,0x90,0x00, 5, // 0x4C 'L' 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xF0,0x00, 5, // 0x4D 'M' 0x00,0x90,0x90,0xF0,0xF0,0x90,0x90,0x90,0x90,0x00, 5, // 0x4E 'N' 0x00,0x90,0x90,0xD0,0xD0,0xB0,0xB0,0x90,0x90,0x00, 5, // 0x4F 'O' 0x00,0x60,0x90,0x90,0x90,0x90,0x90,0x90,0x60,0x00, 5, // 0x50 'P' 0x00,0xE0,0x90,0x90,0x90,0xE0,0x80,0x80,0x80,0x00, 5, // 0x51 'Q' 0x00,0x60,0x90,0x90,0x90,0x90,0x90,0x90,0x60,0x30, 5, // 0x52 'R' 0x00,0xE0,0x90,0x90,0x90,0xE0,0xA0,0x90,0x90,0x00, 5, // 0x53 'S' 0x00,0x60,0x90,0x80,0x60,0x10,0x90,0x90,0x60,0x00, 5, // 0x54 'T' 0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00, 5, // 0x55 'U' 0x00,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x60,0x00, 5, // 0x56 'V' 0x00,0x90,0x90,0x90,0x50,0x50,0x50,0x20,0x20,0x00, 5, // 0x57 'W' 0x00,0x90,0x90,0x90,0x90,0x90,0xF0,0xF0,0x90,0x00, 5, // 0x58 'X' 0x00,0x90,0x90,0x90,0x60,0x60,0x90,0x90,0x90,0x00, 5, // 0x59 'Y' 0x00,0x88,0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x00, 5, // 0x5A 'Z' 0x00,0xF0,0x10,0x20,0x20,0x40,0x40,0x80,0xF0,0x00, 5, // 0x5B '[' 0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x60, 5, // 0x5C '\' 0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08, 5, // 0x5D ']' 0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x60, 5, // 0x5E '^' 0x00,0x20,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x5F '_' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00, 5, // 0x60 '`' 0x00,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x61 'a' 0x00,0x00,0x00,0x60,0x10,0x70,0x90,0x90,0x70,0x00, 5, // 0x62 'b' 0x00,0x80,0x80,0xE0,0x90,0x90,0x90,0x90,0xE0,0x00, 5, // 0x63 'c' 0x00,0x00,0x00,0x60,0x90,0x80,0x80,0x90,0x60,0x00, 5, // 0x64 'd' 0x00,0x10,0x10,0x70,0x90,0x90,0x90,0x90,0x70,0x00, 5, // 0x65 'e' 0x00,0x00,0x00,0x60,0x90,0x90,0xF0,0x80,0x70,0x00, 5, // 0x66 'f' 0x00,0x30,0x40,0xE0,0x40,0x40,0x40,0x40,0x40,0x00, 5, // 0x67 'g' 0x00,0x00,0x00,0x70,0x90,0x90,0x90,0x70,0x10,0xE0, 5, // 0x68 'h' 0x00,0x80,0x80,0xE0,0x90,0x90,0x90,0x90,0x90,0x00, 5, // 0x69 'i' 0x00,0x20,0x00,0x60,0x20,0x20,0x20,0x20,0x70,0x00, 5, // 0x6A 'j' 0x00,0x20,0x00,0x60,0x20,0x20,0x20,0x20,0x20,0xC0, 5, // 0x6B 'k' 0x00,0x80,0x80,0x90,0xA0,0xC0,0xA0,0x90,0x90,0x00, 5, // 0x6C 'l' 0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00, 5, // 0x6D 'm' 0x00,0x00,0x00,0x90,0xF0,0x90,0x90,0x90,0x90,0x00, 5, // 0x6E 'n' 0x00,0x00,0x00,0xE0,0x90,0x90,0x90,0x90,0x90,0x00, 5, // 0x6F 'o' 0x00,0x00,0x00,0x60,0x90,0x90,0x90,0x90,0x60,0x00, 5, // 0x70 'p' 0x00,0x00,0x00,0xE0,0x90,0x90,0x90,0xE0,0x80,0x80, 5, // 0x71 'q' 0x00,0x00,0x00,0x70,0x90,0x90,0x90,0x70,0x10,0x10, 5, // 0x72 'r' 0x00,0x00,0x00,0xB0,0x50,0x40,0x40,0x40,0xE0,0x00, 5, // 0x73 's' 0x00,0x00,0x00,0x60,0x90,0x40,0x20,0x90,0x60,0x00, 5, // 0x74 't' 0x00,0x40,0x40,0xE0,0x40,0x40,0x40,0x50,0x20,0x00, 5, // 0x75 'u' 0x00,0x00,0x00,0x90,0x90,0x90,0x90,0x90,0x70,0x00, 5, // 0x76 'v' 0x00,0x00,0x00,0x90,0x90,0x50,0x50,0x20,0x20,0x00, 5, // 0x77 'w' 0x00,0x00,0x00,0x90,0x90,0x90,0x90,0xF0,0x90,0x00, 5, // 0x78 'x' 0x00,0x00,0x00,0x90,0x90,0x60,0x60,0x90,0x90,0x00, 5, // 0x79 'y' 0x00,0x00,0x00,0x90,0x90,0x90,0x90,0x70,0x10,0xE0, 5, // 0x7A 'z' 0x00,0x00,0x00,0xF0,0x10,0x20,0x40,0x80,0xF0,0x00, 5, // 0x7B '{' 0x30,0x40,0x40,0x40,0x80,0x40,0x40,0x40,0x40,0x30, 5, // 0x7C '|' 0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, 5, // 0x7D '}' 0xC0,0x20,0x20,0x20,0x10,0x20,0x20,0x20,0x20,0xC0, 5, // 0x7E '~' 0x00,0x40,0xA8,0x10,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x7F '' 0x00,0x20,0x70,0xD8,0x88,0x88,0xF8,0x00,0x00,0x00, 0 }; const int8u mcs5x11_mono[] = { 11, 3, 32, 128-32, 0x00,0x00,0x0C,0x00,0x18,0x00,0x24,0x00,0x30,0x00,0x3C,0x00,0x48,0x00,0x54,0x00,0x60,0x00, 0x6C,0x00,0x78,0x00,0x84,0x00,0x90,0x00,0x9C,0x00,0xA8,0x00,0xB4,0x00,0xC0,0x00,0xCC,0x00, 0xD8,0x00,0xE4,0x00,0xF0,0x00,0xFC,0x00,0x08,0x01,0x14,0x01,0x20,0x01,0x2C,0x01,0x38,0x01, 0x44,0x01,0x50,0x01,0x5C,0x01,0x68,0x01,0x74,0x01,0x80,0x01,0x8C,0x01,0x98,0x01,0xA4,0x01, 0xB0,0x01,0xBC,0x01,0xC8,0x01,0xD4,0x01,0xE0,0x01,0xEC,0x01,0xF8,0x01,0x04,0x02,0x10,0x02, 0x1C,0x02,0x28,0x02,0x34,0x02,0x40,0x02,0x4C,0x02,0x58,0x02,0x64,0x02,0x70,0x02,0x7C,0x02, 0x88,0x02,0x94,0x02,0xA0,0x02,0xAC,0x02,0xB8,0x02,0xC4,0x02,0xD0,0x02,0xDC,0x02,0xE8,0x02, 0xF4,0x02,0x00,0x03,0x0C,0x03,0x18,0x03,0x24,0x03,0x30,0x03,0x3C,0x03,0x48,0x03,0x54,0x03, 0x60,0x03,0x6C,0x03,0x78,0x03,0x84,0x03,0x90,0x03,0x9C,0x03,0xA8,0x03,0xB4,0x03,0xC0,0x03, 0xCC,0x03,0xD8,0x03,0xE4,0x03,0xF0,0x03,0xFC,0x03,0x08,0x04,0x14,0x04,0x20,0x04,0x2C,0x04, 0x38,0x04,0x44,0x04,0x50,0x04,0x5C,0x04,0x68,0x04,0x74,0x04, 5, // 0x20 ' ' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x21 '!' 0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00, 5, // 0x22 '"' 0x00,0x50,0x50,0xA0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x23 '#' 0x00,0x50,0x50,0xF8,0x50,0x50,0x50,0xF8,0x50,0x50,0x00, 5, // 0x24 '$' 0x00,0x40,0x60,0x90,0x80,0x60,0x10,0x90,0x60,0x20,0x00, 5, // 0x25 '%' 0x00,0x00,0x90,0x90,0x20,0x20,0x40,0x40,0x90,0x90,0x00, 5, // 0x26 '&' 0x00,0x40,0xA0,0xA0,0x40,0xA8,0x90,0x90,0x68,0x00,0x00, 5, // 0x27 ''' 0x00,0x20,0x20,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x28 '(' 0x00,0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x20,0x20,0x10, 5, // 0x29 ')' 0x00,0x40,0x20,0x20,0x10,0x10,0x10,0x10,0x20,0x20,0x40, 5, // 0x2A '*' 0x00,0x00,0x90,0x60,0xF0,0x60,0x90,0x00,0x00,0x00,0x00, 5, // 0x2B '+' 0x00,0x00,0x00,0x20,0x20,0xF8,0x20,0x20,0x00,0x00,0x00, 5, // 0x2C ',' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x40,0x80, 5, // 0x2D '-' 0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x00, 5, // 0x2E '.' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00, 5, // 0x2F '/' 0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x80,0x00, 5, // 0x30 '0' 0x00,0x70,0x90,0x90,0x90,0x90,0x90,0x90,0xE0,0x00,0x00, 5, // 0x31 '1' 0x00,0x20,0x60,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, 5, // 0x32 '2' 0x00,0x60,0x90,0x90,0x10,0x20,0x40,0x80,0xF0,0x00,0x00, 5, // 0x33 '3' 0x00,0x60,0x90,0x10,0x60,0x10,0x10,0x90,0x60,0x00,0x00, 5, // 0x34 '4' 0x00,0x10,0x30,0x50,0x50,0x90,0xF8,0x10,0x10,0x00,0x00, 5, // 0x35 '5' 0x00,0xF0,0x80,0xE0,0x90,0x10,0x10,0x90,0x60,0x00,0x00, 5, // 0x36 '6' 0x00,0x60,0x90,0x80,0xE0,0x90,0x90,0x90,0x60,0x00,0x00, 5, // 0x37 '7' 0x00,0xF0,0x10,0x10,0x20,0x20,0x40,0x40,0x40,0x00,0x00, 5, // 0x38 '8' 0x00,0x60,0x90,0x90,0x60,0x90,0x90,0x90,0x60,0x00,0x00, 5, // 0x39 '9' 0x00,0x60,0x90,0x90,0x90,0x70,0x10,0x90,0x60,0x00,0x00, 5, // 0x3A ':' 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x60,0x60,0x00,0x00, 5, // 0x3B ';' 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x60,0x60,0x40,0x80, 5, // 0x3C '<' 0x00,0x08,0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x08,0x00, 5, // 0x3D '=' 0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0xF0,0x00,0x00,0x00, 5, // 0x3E '>' 0x00,0x80,0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x80,0x00, 5, // 0x3F '?' 0x00,0x60,0x90,0x10,0x10,0x20,0x40,0x00,0x40,0x00,0x00, 5, // 0x40 '@' 0x00,0x60,0x90,0x90,0xB0,0xB0,0x80,0x80,0x70,0x00,0x00, 5, // 0x41 'A' 0x00,0x60,0x90,0x90,0x90,0xF0,0x90,0x90,0x90,0x00,0x00, 5, // 0x42 'B' 0x00,0xE0,0x90,0x90,0xE0,0x90,0x90,0x90,0xE0,0x00,0x00, 5, // 0x43 'C' 0x00,0x60,0x90,0x80,0x80,0x80,0x80,0x90,0x60,0x00,0x00, 5, // 0x44 'D' 0x00,0xE0,0x90,0x90,0x90,0x90,0x90,0x90,0xE0,0x00,0x00, 5, // 0x45 'E' 0x00,0xF0,0x80,0x80,0xE0,0x80,0x80,0x80,0xF0,0x00,0x00, 5, // 0x46 'F' 0x00,0xF0,0x80,0x80,0xE0,0x80,0x80,0x80,0x80,0x00,0x00, 5, // 0x47 'G' 0x00,0x60,0x90,0x80,0x80,0xB0,0x90,0x90,0x60,0x00,0x00, 5, // 0x48 'H' 0x00,0x90,0x90,0x90,0xF0,0x90,0x90,0x90,0x90,0x00,0x00, 5, // 0x49 'I' 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, 5, // 0x4A 'J' 0x00,0x70,0x20,0x20,0x20,0x20,0xA0,0xA0,0x40,0x00,0x00, 5, // 0x4B 'K' 0x00,0x90,0xA0,0xA0,0xC0,0xA0,0xA0,0x90,0x90,0x00,0x00, 5, // 0x4C 'L' 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xF0,0x00,0x00, 5, // 0x4D 'M' 0x00,0x90,0xF0,0xF0,0x90,0x90,0x90,0x90,0x90,0x00,0x00, 5, // 0x4E 'N' 0x00,0x90,0x90,0xD0,0xD0,0xB0,0xB0,0x90,0x90,0x00,0x00, 5, // 0x4F 'O' 0x00,0x60,0x90,0x90,0x90,0x90,0x90,0x90,0x60,0x00,0x00, 5, // 0x50 'P' 0x00,0xE0,0x90,0x90,0x90,0xE0,0x80,0x80,0x80,0x00,0x00, 5, // 0x51 'Q' 0x00,0x60,0x90,0x90,0x90,0x90,0x90,0x90,0x60,0x30,0x00, 5, // 0x52 'R' 0x00,0xE0,0x90,0x90,0x90,0xE0,0xA0,0x90,0x90,0x00,0x00, 5, // 0x53 'S' 0x00,0x60,0x90,0x80,0x60,0x10,0x90,0x90,0x60,0x00,0x00, 5, // 0x54 'T' 0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00, 5, // 0x55 'U' 0x00,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x60,0x00,0x00, 5, // 0x56 'V' 0x00,0x90,0x90,0x90,0x50,0x50,0x50,0x20,0x20,0x00,0x00, 5, // 0x57 'W' 0x00,0x90,0x90,0x90,0x90,0x90,0xF0,0xF0,0x90,0x00,0x00, 5, // 0x58 'X' 0x00,0x90,0x90,0x90,0x60,0x60,0x90,0x90,0x90,0x00,0x00, 5, // 0x59 'Y' 0x00,0x88,0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x00,0x00, 5, // 0x5A 'Z' 0x00,0xF0,0x10,0x20,0x20,0x40,0x40,0x80,0xF0,0x00,0x00, 5, // 0x5B '[' 0x00,0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x60, 5, // 0x5C '\' 0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x00, 5, // 0x5D ']' 0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x60, 5, // 0x5E '^' 0x00,0x20,0x50,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x5F '_' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00, 5, // 0x60 '`' 0x00,0x40,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x61 'a' 0x00,0x00,0x00,0x60,0x10,0x70,0x90,0x90,0x70,0x00,0x00, 5, // 0x62 'b' 0x00,0x80,0x80,0xE0,0x90,0x90,0x90,0x90,0xE0,0x00,0x00, 5, // 0x63 'c' 0x00,0x00,0x00,0x60,0x90,0x80,0x80,0x90,0x60,0x00,0x00, 5, // 0x64 'd' 0x00,0x10,0x10,0x70,0x90,0x90,0x90,0x90,0x70,0x00,0x00, 5, // 0x65 'e' 0x00,0x00,0x00,0x60,0x90,0x90,0xF0,0x80,0x70,0x00,0x00, 5, // 0x66 'f' 0x00,0x30,0x40,0xE0,0x40,0x40,0x40,0x40,0x40,0x00,0x00, 5, // 0x67 'g' 0x00,0x00,0x00,0x70,0x90,0x90,0x90,0x90,0x70,0x10,0xE0, 5, // 0x68 'h' 0x00,0x80,0x80,0xE0,0x90,0x90,0x90,0x90,0x90,0x00,0x00, 5, // 0x69 'i' 0x00,0x20,0x00,0x60,0x20,0x20,0x20,0x20,0x70,0x00,0x00, 5, // 0x6A 'j' 0x00,0x20,0x00,0x60,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, 5, // 0x6B 'k' 0x00,0x80,0x80,0x90,0xA0,0xC0,0xA0,0x90,0x90,0x00,0x00, 5, // 0x6C 'l' 0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, 5, // 0x6D 'm' 0x00,0x00,0x00,0x90,0xF0,0x90,0x90,0x90,0x90,0x00,0x00, 5, // 0x6E 'n' 0x00,0x00,0x00,0xE0,0x90,0x90,0x90,0x90,0x90,0x00,0x00, 5, // 0x6F 'o' 0x00,0x00,0x00,0x60,0x90,0x90,0x90,0x90,0x60,0x00,0x00, 5, // 0x70 'p' 0x00,0x00,0x00,0xE0,0x90,0x90,0x90,0x90,0xE0,0x80,0x80, 5, // 0x71 'q' 0x00,0x00,0x00,0x70,0x90,0x90,0x90,0x90,0x70,0x10,0x10, 5, // 0x72 'r' 0x00,0x00,0x00,0xA0,0x50,0x40,0x40,0x40,0xE0,0x00,0x00, 5, // 0x73 's' 0x00,0x00,0x00,0x60,0x90,0x40,0x20,0x90,0x60,0x00,0x00, 5, // 0x74 't' 0x00,0x40,0x40,0xE0,0x40,0x40,0x40,0x40,0x30,0x00,0x00, 5, // 0x75 'u' 0x00,0x00,0x00,0x90,0x90,0x90,0x90,0x90,0x70,0x00,0x00, 5, // 0x76 'v' 0x00,0x00,0x00,0x90,0x90,0x50,0x50,0x20,0x20,0x00,0x00, 5, // 0x77 'w' 0x00,0x00,0x00,0x90,0x90,0x90,0x90,0xF0,0x90,0x00,0x00, 5, // 0x78 'x' 0x00,0x00,0x00,0x90,0x90,0x60,0x60,0x90,0x90,0x00,0x00, 5, // 0x79 'y' 0x00,0x00,0x00,0x90,0x90,0x90,0x90,0x90,0x70,0x10,0xE0, 5, // 0x7A 'z' 0x00,0x00,0x00,0xF0,0x10,0x20,0x40,0x80,0xF0,0x00,0x00, 5, // 0x7B '{' 0x30,0x40,0x40,0x40,0x40,0x80,0x40,0x40,0x40,0x40,0x30, 5, // 0x7C '|' 0x00,0x20,0x20,0x20,0x20,0x00,0x20,0x20,0x20,0x20,0x00, 5, // 0x7D '}' 0xC0,0x20,0x20,0x20,0x20,0x10,0x20,0x20,0x20,0x20,0xC0, 5, // 0x7E '~' 0x00,0x40,0xA8,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x7F '' 0x00,0x20,0x70,0xD8,0x88,0x88,0xF8,0x00,0x00,0x00,0x00, 0 }; const int8u mcs6x10_mono[] = { 10, 3, 32, 128-32, 0x00,0x00,0x0B,0x00,0x16,0x00,0x21,0x00,0x2C,0x00,0x37,0x00,0x42,0x00,0x4D,0x00,0x58,0x00, 0x63,0x00,0x6E,0x00,0x79,0x00,0x84,0x00,0x8F,0x00,0x9A,0x00,0xA5,0x00,0xB0,0x00,0xBB,0x00, 0xC6,0x00,0xD1,0x00,0xDC,0x00,0xE7,0x00,0xF2,0x00,0xFD,0x00,0x08,0x01,0x13,0x01,0x1E,0x01, 0x29,0x01,0x34,0x01,0x3F,0x01,0x4A,0x01,0x55,0x01,0x60,0x01,0x6B,0x01,0x76,0x01,0x81,0x01, 0x8C,0x01,0x97,0x01,0xA2,0x01,0xAD,0x01,0xB8,0x01,0xC3,0x01,0xCE,0x01,0xD9,0x01,0xE4,0x01, 0xEF,0x01,0xFA,0x01,0x05,0x02,0x10,0x02,0x1B,0x02,0x26,0x02,0x31,0x02,0x3C,0x02,0x47,0x02, 0x52,0x02,0x5D,0x02,0x68,0x02,0x73,0x02,0x7E,0x02,0x89,0x02,0x94,0x02,0x9F,0x02,0xAA,0x02, 0xB5,0x02,0xC0,0x02,0xCB,0x02,0xD6,0x02,0xE1,0x02,0xEC,0x02,0xF7,0x02,0x02,0x03,0x0D,0x03, 0x18,0x03,0x23,0x03,0x2E,0x03,0x39,0x03,0x44,0x03,0x4F,0x03,0x5A,0x03,0x65,0x03,0x70,0x03, 0x7B,0x03,0x86,0x03,0x91,0x03,0x9C,0x03,0xA7,0x03,0xB2,0x03,0xBD,0x03,0xC8,0x03,0xD3,0x03, 0xDE,0x03,0xE9,0x03,0xF4,0x03,0xFF,0x03,0x0A,0x04,0x15,0x04, 6, // 0x20 ' ' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x21 '!' 0x00,0x10,0x10,0x10,0x10,0x10,0x00,0x10,0x00,0x00, 6, // 0x22 '"' 0x00,0x28,0x28,0x50,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x23 '#' 0x00,0x28,0x28,0x7C,0x28,0x28,0x7C,0x28,0x28,0x00, 6, // 0x24 '$' 0x10,0x38,0x54,0x50,0x38,0x14,0x54,0x38,0x10,0x00, 6, // 0x25 '%' 0x00,0x08,0xC8,0xD0,0x10,0x20,0x2C,0x4C,0x40,0x00, 6, // 0x26 '&' 0x00,0x20,0x50,0x50,0x24,0x54,0x48,0x34,0x00,0x00, 6, // 0x27 ''' 0x00,0x10,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x28 '(' 0x08,0x10,0x10,0x20,0x20,0x20,0x10,0x10,0x08,0x00, 6, // 0x29 ')' 0x20,0x10,0x10,0x08,0x08,0x08,0x10,0x10,0x20,0x00, 6, // 0x2A '*' 0x00,0x00,0x28,0x7C,0x38,0x7C,0x28,0x00,0x00,0x00, 6, // 0x2B '+' 0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00,0x00, 6, // 0x2C ',' 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x20,0x40, 6, // 0x2D '-' 0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00, 6, // 0x2E '.' 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00, 6, // 0x2F '/' 0x00,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x00, 6, // 0x30 '0' 0x00,0x38,0x44,0x4C,0x54,0x64,0x44,0x38,0x00,0x00, 6, // 0x31 '1' 0x00,0x10,0x30,0x10,0x10,0x10,0x10,0x38,0x00,0x00, 6, // 0x32 '2' 0x00,0x38,0x44,0x04,0x18,0x20,0x40,0x7C,0x00,0x00, 6, // 0x33 '3' 0x00,0x38,0x44,0x04,0x38,0x04,0x44,0x38,0x00,0x00, 6, // 0x34 '4' 0x00,0x08,0x18,0x28,0x48,0x7C,0x08,0x08,0x00,0x00, 6, // 0x35 '5' 0x00,0x7C,0x40,0x40,0x78,0x04,0x44,0x38,0x00,0x00, 6, // 0x36 '6' 0x00,0x38,0x40,0x40,0x78,0x44,0x44,0x38,0x00,0x00, 6, // 0x37 '7' 0x00,0x7C,0x04,0x08,0x10,0x20,0x20,0x20,0x00,0x00, 6, // 0x38 '8' 0x00,0x38,0x44,0x44,0x38,0x44,0x44,0x38,0x00,0x00, 6, // 0x39 '9' 0x00,0x38,0x44,0x44,0x3C,0x04,0x04,0x38,0x00,0x00, 6, // 0x3A ':' 0x00,0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x00,0x00, 6, // 0x3B ';' 0x00,0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x20,0x40, 6, // 0x3C '<' 0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x00, 6, // 0x3D '=' 0x00,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x00, 6, // 0x3E '>' 0x40,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x40,0x00, 6, // 0x3F '?' 0x00,0x38,0x44,0x04,0x18,0x10,0x00,0x10,0x00,0x00, 6, // 0x40 '@' 0x00,0x38,0x44,0x5C,0x54,0x5C,0x40,0x38,0x00,0x00, 6, // 0x41 'A' 0x00,0x38,0x44,0x44,0x44,0x7C,0x44,0x44,0x00,0x00, 6, // 0x42 'B' 0x00,0x78,0x44,0x44,0x78,0x44,0x44,0x78,0x00,0x00, 6, // 0x43 'C' 0x00,0x38,0x44,0x40,0x40,0x40,0x44,0x38,0x00,0x00, 6, // 0x44 'D' 0x00,0x78,0x44,0x44,0x44,0x44,0x44,0x78,0x00,0x00, 6, // 0x45 'E' 0x00,0x7C,0x40,0x40,0x78,0x40,0x40,0x7C,0x00,0x00, 6, // 0x46 'F' 0x00,0x7C,0x40,0x40,0x78,0x40,0x40,0x40,0x00,0x00, 6, // 0x47 'G' 0x00,0x38,0x44,0x40,0x4C,0x44,0x44,0x3C,0x00,0x00, 6, // 0x48 'H' 0x00,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x00,0x00, 6, // 0x49 'I' 0x00,0x38,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, 6, // 0x4A 'J' 0x00,0x1C,0x08,0x08,0x08,0x48,0x48,0x30,0x00,0x00, 6, // 0x4B 'K' 0x00,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x00,0x00, 6, // 0x4C 'L' 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x7C,0x00,0x00, 6, // 0x4D 'M' 0x00,0x44,0x6C,0x54,0x54,0x44,0x44,0x44,0x00,0x00, 6, // 0x4E 'N' 0x00,0x44,0x44,0x64,0x54,0x4C,0x44,0x44,0x00,0x00, 6, // 0x4F 'O' 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, 6, // 0x50 'P' 0x00,0x78,0x44,0x44,0x78,0x40,0x40,0x40,0x00,0x00, 6, // 0x51 'Q' 0x00,0x38,0x44,0x44,0x44,0x54,0x48,0x34,0x00,0x00, 6, // 0x52 'R' 0x00,0x78,0x44,0x44,0x78,0x48,0x44,0x44,0x00,0x00, 6, // 0x53 'S' 0x00,0x38,0x44,0x40,0x38,0x04,0x44,0x38,0x00,0x00, 6, // 0x54 'T' 0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, 6, // 0x55 'U' 0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, 6, // 0x56 'V' 0x00,0x44,0x44,0x44,0x44,0x28,0x28,0x10,0x00,0x00, 6, // 0x57 'W' 0x00,0x44,0x44,0x54,0x54,0x54,0x54,0x28,0x00,0x00, 6, // 0x58 'X' 0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x00,0x00, 6, // 0x59 'Y' 0x00,0x44,0x44,0x44,0x28,0x10,0x10,0x10,0x00,0x00, 6, // 0x5A 'Z' 0x00,0x78,0x08,0x10,0x20,0x40,0x40,0x78,0x00,0x00, 6, // 0x5B '[' 0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x38,0x00, 6, // 0x5C '\' 0x00,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x00, 6, // 0x5D ']' 0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x38,0x00, 6, // 0x5E '^' 0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x5F '_' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00, 6, // 0x60 '`' 0x00,0x10,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x61 'a' 0x00,0x00,0x00,0x38,0x04,0x3C,0x44,0x3C,0x00,0x00, 6, // 0x62 'b' 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x78,0x00,0x00, 6, // 0x63 'c' 0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x3C,0x00,0x00, 6, // 0x64 'd' 0x00,0x04,0x04,0x3C,0x44,0x44,0x44,0x3C,0x00,0x00, 6, // 0x65 'e' 0x00,0x00,0x00,0x38,0x44,0x78,0x40,0x3C,0x00,0x00, 6, // 0x66 'f' 0x00,0x0C,0x10,0x10,0x38,0x10,0x10,0x10,0x00,0x00, 6, // 0x67 'g' 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x3C,0x04,0x38, 6, // 0x68 'h' 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x00,0x00, 6, // 0x69 'i' 0x00,0x10,0x00,0x30,0x10,0x10,0x10,0x38,0x00,0x00, 6, // 0x6A 'j' 0x00,0x08,0x00,0x18,0x08,0x08,0x08,0x08,0x48,0x30, 6, // 0x6B 'k' 0x00,0x40,0x40,0x48,0x50,0x60,0x50,0x48,0x00,0x00, 6, // 0x6C 'l' 0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, 6, // 0x6D 'm' 0x00,0x00,0x00,0x68,0x54,0x54,0x44,0x44,0x00,0x00, 6, // 0x6E 'n' 0x00,0x00,0x00,0x58,0x64,0x44,0x44,0x44,0x00,0x00, 6, // 0x6F 'o' 0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x38,0x00,0x00, 6, // 0x70 'p' 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x78,0x40,0x40, 6, // 0x71 'q' 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x3C,0x04,0x04, 6, // 0x72 'r' 0x00,0x00,0x00,0x58,0x24,0x20,0x20,0x70,0x00,0x00, 6, // 0x73 's' 0x00,0x00,0x00,0x38,0x40,0x38,0x04,0x78,0x00,0x00, 6, // 0x74 't' 0x00,0x10,0x10,0x38,0x10,0x10,0x14,0x08,0x00,0x00, 6, // 0x75 'u' 0x00,0x00,0x00,0x44,0x44,0x44,0x4C,0x34,0x00,0x00, 6, // 0x76 'v' 0x00,0x00,0x00,0x44,0x44,0x44,0x28,0x10,0x00,0x00, 6, // 0x77 'w' 0x00,0x00,0x00,0x44,0x44,0x54,0x7C,0x28,0x00,0x00, 6, // 0x78 'x' 0x00,0x00,0x00,0x48,0x48,0x30,0x48,0x48,0x00,0x00, 6, // 0x79 'y' 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x3C,0x04,0x38, 6, // 0x7A 'z' 0x00,0x00,0x00,0x78,0x08,0x30,0x40,0x78,0x00,0x00, 6, // 0x7B '{' 0x18,0x20,0x20,0x20,0xC0,0x20,0x20,0x20,0x18,0x00, 6, // 0x7C '|' 0x10,0x10,0x10,0x10,0x00,0x10,0x10,0x10,0x10,0x00, 6, // 0x7D '}' 0x60,0x10,0x10,0x10,0x0C,0x10,0x10,0x10,0x60,0x00, 6, // 0x7E '~' 0x00,0x48,0xA8,0x90,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x7F '' 0x00,0x10,0x38,0x6C,0x44,0x44,0x7C,0x00,0x00,0x00, 0 }; const int8u mcs6x11_mono[] = { 11, 3, 32, 128-32, 0x00,0x00,0x0C,0x00,0x18,0x00,0x24,0x00,0x30,0x00,0x3C,0x00,0x48,0x00,0x54,0x00,0x60,0x00, 0x6C,0x00,0x78,0x00,0x84,0x00,0x90,0x00,0x9C,0x00,0xA8,0x00,0xB4,0x00,0xC0,0x00,0xCC,0x00, 0xD8,0x00,0xE4,0x00,0xF0,0x00,0xFC,0x00,0x08,0x01,0x14,0x01,0x20,0x01,0x2C,0x01,0x38,0x01, 0x44,0x01,0x50,0x01,0x5C,0x01,0x68,0x01,0x74,0x01,0x80,0x01,0x8C,0x01,0x98,0x01,0xA4,0x01, 0xB0,0x01,0xBC,0x01,0xC8,0x01,0xD4,0x01,0xE0,0x01,0xEC,0x01,0xF8,0x01,0x04,0x02,0x10,0x02, 0x1C,0x02,0x28,0x02,0x34,0x02,0x40,0x02,0x4C,0x02,0x58,0x02,0x64,0x02,0x70,0x02,0x7C,0x02, 0x88,0x02,0x94,0x02,0xA0,0x02,0xAC,0x02,0xB8,0x02,0xC4,0x02,0xD0,0x02,0xDC,0x02,0xE8,0x02, 0xF4,0x02,0x00,0x03,0x0C,0x03,0x18,0x03,0x24,0x03,0x30,0x03,0x3C,0x03,0x48,0x03,0x54,0x03, 0x60,0x03,0x6C,0x03,0x78,0x03,0x84,0x03,0x90,0x03,0x9C,0x03,0xA8,0x03,0xB4,0x03,0xC0,0x03, 0xCC,0x03,0xD8,0x03,0xE4,0x03,0xF0,0x03,0xFC,0x03,0x08,0x04,0x14,0x04,0x20,0x04,0x2C,0x04, 0x38,0x04,0x44,0x04,0x50,0x04,0x5C,0x04,0x68,0x04,0x74,0x04, 6, // 0x20 ' ' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x21 '!' 0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00, 6, // 0x22 '"' 0x00,0x28,0x28,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x23 '#' 0x00,0x28,0x28,0x7C,0x28,0x28,0x7C,0x28,0x28,0x00,0x00, 6, // 0x24 '$' 0x00,0x10,0x38,0x54,0x50,0x38,0x14,0x54,0x38,0x10,0x00, 6, // 0x25 '%' 0x00,0x68,0xA8,0xD0,0x10,0x20,0x2C,0x54,0x58,0x00,0x00, 6, // 0x26 '&' 0x00,0x20,0x50,0x50,0x20,0x54,0x54,0x48,0x34,0x00,0x00, 6, // 0x27 ''' 0x00,0x10,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x28 '(' 0x08,0x10,0x10,0x20,0x20,0x20,0x20,0x10,0x10,0x08,0x00, 6, // 0x29 ')' 0x20,0x10,0x10,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x00, 6, // 0x2A '*' 0x00,0x00,0x28,0x7C,0x38,0x7C,0x28,0x00,0x00,0x00,0x00, 6, // 0x2B '+' 0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00,0x00, 6, // 0x2C ',' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x20,0x40, 6, // 0x2D '-' 0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00, 6, // 0x2E '.' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00, 6, // 0x2F '/' 0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x00, 6, // 0x30 '0' 0x00,0x38,0x44,0x44,0x54,0x54,0x44,0x44,0x38,0x00,0x00, 6, // 0x31 '1' 0x00,0x10,0x30,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, 6, // 0x32 '2' 0x00,0x38,0x44,0x44,0x08,0x10,0x20,0x40,0x7C,0x00,0x00, 6, // 0x33 '3' 0x00,0x38,0x44,0x04,0x38,0x04,0x04,0x44,0x38,0x00,0x00, 6, // 0x34 '4' 0x00,0x08,0x18,0x28,0x28,0x48,0x7C,0x08,0x08,0x00,0x00, 6, // 0x35 '5' 0x00,0x7C,0x40,0x78,0x44,0x04,0x04,0x44,0x38,0x00,0x00, 6, // 0x36 '6' 0x00,0x38,0x44,0x40,0x78,0x44,0x44,0x44,0x38,0x00,0x00, 6, // 0x37 '7' 0x00,0x7C,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x00,0x00, 6, // 0x38 '8' 0x00,0x38,0x44,0x44,0x38,0x44,0x44,0x44,0x38,0x00,0x00, 6, // 0x39 '9' 0x00,0x38,0x44,0x44,0x3C,0x04,0x04,0x44,0x38,0x00,0x00, 6, // 0x3A ':' 0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x00,0x00, 6, // 0x3B ';' 0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x20,0x40, 6, // 0x3C '<' 0x00,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x00, 6, // 0x3D '=' 0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x00, 6, // 0x3E '>' 0x00,0x40,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x40,0x00, 6, // 0x3F '?' 0x00,0x38,0x44,0x04,0x08,0x10,0x10,0x00,0x10,0x00,0x00, 6, // 0x40 '@' 0x00,0x38,0x44,0x5C,0x54,0x54,0x4C,0x40,0x38,0x00,0x00, 6, // 0x41 'A' 0x00,0x38,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x00,0x00, 6, // 0x42 'B' 0x00,0x78,0x44,0x44,0x78,0x44,0x44,0x44,0x78,0x00,0x00, 6, // 0x43 'C' 0x00,0x38,0x44,0x40,0x40,0x40,0x40,0x44,0x38,0x00,0x00, 6, // 0x44 'D' 0x00,0x70,0x48,0x44,0x44,0x44,0x44,0x48,0x70,0x00,0x00, 6, // 0x45 'E' 0x00,0x7C,0x40,0x40,0x78,0x40,0x40,0x40,0x7C,0x00,0x00, 6, // 0x46 'F' 0x00,0x7C,0x40,0x40,0x78,0x40,0x40,0x40,0x40,0x00,0x00, 6, // 0x47 'G' 0x00,0x38,0x44,0x40,0x40,0x5C,0x44,0x4C,0x34,0x00,0x00, 6, // 0x48 'H' 0x00,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0x00,0x00, 6, // 0x49 'I' 0x00,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, 6, // 0x4A 'J' 0x00,0x1C,0x08,0x08,0x08,0x08,0x48,0x48,0x30,0x00,0x00, 6, // 0x4B 'K' 0x00,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x44,0x00,0x00, 6, // 0x4C 'L' 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7C,0x00,0x00, 6, // 0x4D 'M' 0x00,0x44,0x6C,0x54,0x54,0x54,0x44,0x44,0x44,0x00,0x00, 6, // 0x4E 'N' 0x00,0x44,0x64,0x64,0x54,0x54,0x4C,0x4C,0x44,0x00,0x00, 6, // 0x4F 'O' 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, 6, // 0x50 'P' 0x00,0x78,0x44,0x44,0x44,0x78,0x40,0x40,0x40,0x00,0x00, 6, // 0x51 'Q' 0x00,0x38,0x44,0x44,0x44,0x44,0x54,0x48,0x34,0x00,0x00, 6, // 0x52 'R' 0x00,0x78,0x44,0x44,0x44,0x78,0x48,0x44,0x44,0x00,0x00, 6, // 0x53 'S' 0x00,0x38,0x44,0x40,0x38,0x04,0x04,0x44,0x38,0x00,0x00, 6, // 0x54 'T' 0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, 6, // 0x55 'U' 0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, 6, // 0x56 'V' 0x00,0x44,0x44,0x44,0x28,0x28,0x28,0x10,0x10,0x00,0x00, 6, // 0x57 'W' 0x00,0x44,0x44,0x54,0x54,0x54,0x54,0x54,0x28,0x00,0x00, 6, // 0x58 'X' 0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x44,0x00,0x00, 6, // 0x59 'Y' 0x00,0x44,0x44,0x44,0x28,0x10,0x10,0x10,0x10,0x00,0x00, 6, // 0x5A 'Z' 0x00,0x7C,0x04,0x08,0x10,0x20,0x40,0x40,0x7C,0x00,0x00, 6, // 0x5B '[' 0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x38,0x00, 6, // 0x5C '\' 0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x00, 6, // 0x5D ']' 0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x38,0x00, 6, // 0x5E '^' 0x00,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x5F '_' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00, 6, // 0x60 '`' 0x00,0x20,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x61 'a' 0x00,0x00,0x00,0x38,0x04,0x3C,0x44,0x44,0x3C,0x00,0x00, 6, // 0x62 'b' 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x78,0x00,0x00, 6, // 0x63 'c' 0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x44,0x38,0x00,0x00, 6, // 0x64 'd' 0x00,0x04,0x04,0x3C,0x44,0x44,0x44,0x44,0x3C,0x00,0x00, 6, // 0x65 'e' 0x00,0x00,0x00,0x38,0x44,0x7C,0x40,0x44,0x38,0x00,0x00, 6, // 0x66 'f' 0x00,0x0C,0x10,0x38,0x10,0x10,0x10,0x10,0x10,0x00,0x00, 6, // 0x67 'g' 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x3C,0x04,0x78, 6, // 0x68 'h' 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x00,0x00, 6, // 0x69 'i' 0x00,0x10,0x00,0x30,0x10,0x10,0x10,0x10,0x38,0x00,0x00, 6, // 0x6A 'j' 0x00,0x10,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x50,0x20, 6, // 0x6B 'k' 0x00,0x40,0x40,0x4C,0x50,0x60,0x50,0x48,0x44,0x00,0x00, 6, // 0x6C 'l' 0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, 6, // 0x6D 'm' 0x00,0x00,0x00,0x68,0x54,0x54,0x54,0x44,0x44,0x00,0x00, 6, // 0x6E 'n' 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x44,0x00,0x00, 6, // 0x6F 'o' 0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x38,0x00,0x00, 6, // 0x70 'p' 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x40,0x40, 6, // 0x71 'q' 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x3C,0x04,0x04, 6, // 0x72 'r' 0x00,0x00,0x00,0x58,0x24,0x20,0x20,0x20,0x70,0x00,0x00, 6, // 0x73 's' 0x00,0x00,0x00,0x38,0x44,0x30,0x08,0x44,0x38,0x00,0x00, 6, // 0x74 't' 0x00,0x20,0x20,0x70,0x20,0x20,0x20,0x20,0x18,0x00,0x00, 6, // 0x75 'u' 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x4C,0x34,0x00,0x00, 6, // 0x76 'v' 0x00,0x00,0x00,0x44,0x44,0x28,0x28,0x10,0x10,0x00,0x00, 6, // 0x77 'w' 0x00,0x00,0x00,0x44,0x44,0x44,0x54,0x7C,0x28,0x00,0x00, 6, // 0x78 'x' 0x00,0x00,0x00,0x44,0x28,0x10,0x28,0x44,0x44,0x00,0x00, 6, // 0x79 'y' 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x3C,0x08,0x70, 6, // 0x7A 'z' 0x00,0x00,0x00,0x7C,0x08,0x10,0x20,0x40,0x7C,0x00,0x00, 6, // 0x7B '{' 0x18,0x20,0x20,0x20,0xC0,0xC0,0x20,0x20,0x20,0x18,0x00, 6, // 0x7C '|' 0x00,0x10,0x10,0x10,0x10,0x00,0x10,0x10,0x10,0x10,0x00, 6, // 0x7D '}' 0x60,0x10,0x10,0x10,0x0C,0x0C,0x10,0x10,0x10,0x60,0x00, 6, // 0x7E '~' 0x00,0x24,0x54,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x7F '' 0x00,0x10,0x38,0x6C,0x44,0x44,0x7C,0x00,0x00,0x00,0x00, 0 }; const int8u mcs7x12_mono_high[] = { 12, 3, 32, 128-32, 0x00,0x00,0x0D,0x00,0x1A,0x00,0x27,0x00,0x34,0x00,0x41,0x00,0x4E,0x00,0x5B,0x00,0x68,0x00, 0x75,0x00,0x82,0x00,0x8F,0x00,0x9C,0x00,0xA9,0x00,0xB6,0x00,0xC3,0x00,0xD0,0x00,0xDD,0x00, 0xEA,0x00,0xF7,0x00,0x04,0x01,0x11,0x01,0x1E,0x01,0x2B,0x01,0x38,0x01,0x45,0x01,0x52,0x01, 0x5F,0x01,0x6C,0x01,0x79,0x01,0x86,0x01,0x93,0x01,0xA0,0x01,0xAD,0x01,0xBA,0x01,0xC7,0x01, 0xD4,0x01,0xE1,0x01,0xEE,0x01,0xFB,0x01,0x08,0x02,0x15,0x02,0x22,0x02,0x2F,0x02,0x3C,0x02, 0x49,0x02,0x56,0x02,0x63,0x02,0x70,0x02,0x7D,0x02,0x8A,0x02,0x97,0x02,0xA4,0x02,0xB1,0x02, 0xBE,0x02,0xCB,0x02,0xD8,0x02,0xE5,0x02,0xF2,0x02,0xFF,0x02,0x0C,0x03,0x19,0x03,0x26,0x03, 0x33,0x03,0x40,0x03,0x4D,0x03,0x5A,0x03,0x67,0x03,0x74,0x03,0x81,0x03,0x8E,0x03,0x9B,0x03, 0xA8,0x03,0xB5,0x03,0xC2,0x03,0xCF,0x03,0xDC,0x03,0xE9,0x03,0xF6,0x03,0x03,0x04,0x10,0x04, 0x1D,0x04,0x2A,0x04,0x37,0x04,0x44,0x04,0x51,0x04,0x5E,0x04,0x6B,0x04,0x78,0x04,0x85,0x04, 0x92,0x04,0x9F,0x04,0xAC,0x04,0xB9,0x04,0xC6,0x04,0xD3,0x04, 7, // 0x20 ' ' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x21 '!' 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x10,0x00,0x00, 7, // 0x22 '"' 0x28,0x28,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x23 '#' 0x24,0x24,0x24,0x7E,0x24,0x24,0x24,0x7E,0x24,0x24,0x24,0x00, 7, // 0x24 '$' 0x10,0x10,0x38,0x54,0x50,0x38,0x14,0x54,0x38,0x10,0x10,0x00, 7, // 0x25 '%' 0x32,0x54,0x64,0x08,0x08,0x10,0x10,0x26,0x2A,0x4C,0x00,0x00, 7, // 0x26 '&' 0x00,0x20,0x50,0x50,0x50,0x20,0x54,0x54,0x48,0x34,0x00,0x00, 7, // 0x27 ''' 0x10,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x28 '(' 0x08,0x10,0x10,0x20,0x20,0x20,0x20,0x20,0x10,0x10,0x08,0x00, 7, // 0x29 ')' 0x20,0x10,0x10,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x00, 7, // 0x2A '*' 0x00,0x00,0x10,0x54,0x38,0x7C,0x38,0x54,0x10,0x00,0x00,0x00, 7, // 0x2B '+' 0x00,0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00,0x00, 7, // 0x2C ',' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x20,0x40, 7, // 0x2D '-' 0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00, 7, // 0x2E '.' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00, 7, // 0x2F '/' 0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x00,0x00, 7, // 0x30 '0' 0x00,0x38,0x44,0x44,0x54,0x54,0x54,0x44,0x44,0x38,0x00,0x00, 7, // 0x31 '1' 0x00,0x10,0x30,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, 7, // 0x32 '2' 0x00,0x38,0x44,0x04,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,0x00, 7, // 0x33 '3' 0x00,0x38,0x44,0x04,0x04,0x38,0x04,0x04,0x44,0x38,0x00,0x00, 7, // 0x34 '4' 0x00,0x08,0x18,0x28,0x28,0x48,0x48,0x7C,0x08,0x08,0x00,0x00, 7, // 0x35 '5' 0x00,0x7C,0x40,0x40,0x78,0x44,0x04,0x04,0x44,0x38,0x00,0x00, 7, // 0x36 '6' 0x00,0x38,0x44,0x40,0x78,0x44,0x44,0x44,0x44,0x38,0x00,0x00, 7, // 0x37 '7' 0x00,0x7C,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x20,0x00,0x00, 7, // 0x38 '8' 0x00,0x38,0x44,0x44,0x44,0x38,0x44,0x44,0x44,0x38,0x00,0x00, 7, // 0x39 '9' 0x00,0x38,0x44,0x44,0x44,0x3C,0x04,0x04,0x44,0x38,0x00,0x00, 7, // 0x3A ':' 0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x30,0x30,0x00,0x00, 7, // 0x3B ';' 0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x30,0x30,0x20,0x40, 7, // 0x3C '<' 0x00,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x00,0x00, 7, // 0x3D '=' 0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x00,0x00, 7, // 0x3E '>' 0x00,0x40,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x40,0x00,0x00, 7, // 0x3F '?' 0x00,0x38,0x44,0x04,0x04,0x08,0x10,0x10,0x00,0x10,0x00,0x00, 7, // 0x40 '@' 0x00,0x38,0x44,0x44,0x5C,0x54,0x54,0x4C,0x40,0x38,0x00,0x00, 7, // 0x41 'A' 0x00,0x38,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0x00,0x00, 7, // 0x42 'B' 0x00,0x78,0x44,0x44,0x44,0x78,0x44,0x44,0x44,0x78,0x00,0x00, 7, // 0x43 'C' 0x00,0x38,0x44,0x40,0x40,0x40,0x40,0x40,0x44,0x38,0x00,0x00, 7, // 0x44 'D' 0x00,0x70,0x48,0x44,0x44,0x44,0x44,0x44,0x48,0x70,0x00,0x00, 7, // 0x45 'E' 0x00,0x7C,0x40,0x40,0x40,0x78,0x40,0x40,0x40,0x7C,0x00,0x00, 7, // 0x46 'F' 0x00,0x7C,0x40,0x40,0x40,0x78,0x40,0x40,0x40,0x40,0x00,0x00, 7, // 0x47 'G' 0x00,0x38,0x44,0x40,0x40,0x5C,0x44,0x44,0x4C,0x34,0x00,0x00, 7, // 0x48 'H' 0x00,0x44,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0x00,0x00, 7, // 0x49 'I' 0x00,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, 7, // 0x4A 'J' 0x00,0x1C,0x08,0x08,0x08,0x08,0x08,0x48,0x48,0x30,0x00,0x00, 7, // 0x4B 'K' 0x00,0x44,0x48,0x50,0x60,0x60,0x50,0x48,0x44,0x44,0x00,0x00, 7, // 0x4C 'L' 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7C,0x00,0x00, 7, // 0x4D 'M' 0x00,0x44,0x6C,0x6C,0x54,0x54,0x44,0x44,0x44,0x44,0x00,0x00, 7, // 0x4E 'N' 0x00,0x44,0x64,0x64,0x54,0x54,0x4C,0x4C,0x44,0x44,0x00,0x00, 7, // 0x4F 'O' 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, 7, // 0x50 'P' 0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x40,0x40,0x40,0x00,0x00, 7, // 0x51 'Q' 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x54,0x48,0x34,0x00,0x00, 7, // 0x52 'R' 0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x48,0x44,0x44,0x00,0x00, 7, // 0x53 'S' 0x00,0x38,0x44,0x40,0x40,0x38,0x04,0x04,0x44,0x38,0x00,0x00, 7, // 0x54 'T' 0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, 7, // 0x55 'U' 0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, 7, // 0x56 'V' 0x00,0x44,0x44,0x44,0x44,0x28,0x28,0x28,0x10,0x10,0x00,0x00, 7, // 0x57 'W' 0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x54,0x54,0x28,0x00,0x00, 7, // 0x58 'X' 0x00,0x44,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x44,0x00,0x00, 7, // 0x59 'Y' 0x00,0x44,0x44,0x44,0x44,0x28,0x10,0x10,0x10,0x10,0x00,0x00, 7, // 0x5A 'Z' 0x00,0x7C,0x04,0x04,0x08,0x10,0x20,0x40,0x40,0x7C,0x00,0x00, 7, // 0x5B '[' 0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x38,0x00, 7, // 0x5C '\' 0x00,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x00, 7, // 0x5D ']' 0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x38,0x00, 7, // 0x5E '^' 0x00,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x5F '_' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00, 7, // 0x60 '`' 0x00,0x20,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x61 'a' 0x00,0x00,0x00,0x38,0x04,0x3C,0x44,0x44,0x44,0x3C,0x00,0x00, 7, // 0x62 'b' 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x78,0x00,0x00, 7, // 0x63 'c' 0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x40,0x44,0x38,0x00,0x00, 7, // 0x64 'd' 0x00,0x04,0x04,0x3C,0x44,0x44,0x44,0x44,0x44,0x3C,0x00,0x00, 7, // 0x65 'e' 0x00,0x00,0x00,0x38,0x44,0x44,0x7C,0x40,0x44,0x38,0x00,0x00, 7, // 0x66 'f' 0x00,0x0C,0x10,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, 7, // 0x67 'g' 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x44,0x3C,0x04,0x78, 7, // 0x68 'h' 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x44,0x00,0x00, 7, // 0x69 'i' 0x00,0x10,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, 7, // 0x6A 'j' 0x00,0x08,0x00,0x18,0x08,0x08,0x08,0x08,0x08,0x08,0x48,0x30, 7, // 0x6B 'k' 0x00,0x40,0x40,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x00,0x00, 7, // 0x6C 'l' 0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, 7, // 0x6D 'm' 0x00,0x00,0x00,0x68,0x54,0x54,0x44,0x44,0x44,0x44,0x00,0x00, 7, // 0x6E 'n' 0x00,0x00,0x00,0x58,0x64,0x44,0x44,0x44,0x44,0x44,0x00,0x00, 7, // 0x6F 'o' 0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, 7, // 0x70 'p' 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x44,0x78,0x40,0x40, 7, // 0x71 'q' 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x44,0x3C,0x04,0x04, 7, // 0x72 'r' 0x00,0x00,0x00,0x58,0x24,0x20,0x20,0x20,0x20,0x70,0x00,0x00, 7, // 0x73 's' 0x00,0x00,0x00,0x38,0x44,0x40,0x38,0x04,0x44,0x38,0x00,0x00, 7, // 0x74 't' 0x00,0x20,0x20,0x70,0x20,0x20,0x20,0x20,0x24,0x18,0x00,0x00, 7, // 0x75 'u' 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x4C,0x34,0x00,0x00, 7, // 0x76 'v' 0x00,0x00,0x00,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x00,0x00, 7, // 0x77 'w' 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x54,0x54,0x28,0x00,0x00, 7, // 0x78 'x' 0x00,0x00,0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x00,0x00, 7, // 0x79 'y' 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x3C,0x08,0x70, 7, // 0x7A 'z' 0x00,0x00,0x00,0x7C,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,0x00, 7, // 0x7B '{' 0x18,0x20,0x20,0x20,0x20,0xC0,0x20,0x20,0x20,0x20,0x18,0x00, 7, // 0x7C '|' 0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00, 7, // 0x7D '}' 0x60,0x10,0x10,0x10,0x10,0x0C,0x10,0x10,0x10,0x10,0x60,0x00, 7, // 0x7E '~' 0x00,0x60,0x92,0x92,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x7F '' 0x00,0x10,0x38,0x6C,0x44,0x44,0x7C,0x00,0x00,0x00,0x00,0x00, 0 }; const int8u mcs7x12_mono_low[] = { 12, 4, 32, 128-32, 0x00,0x00,0x0D,0x00,0x1A,0x00,0x27,0x00,0x34,0x00,0x41,0x00,0x4E,0x00,0x5B,0x00,0x68,0x00, 0x75,0x00,0x82,0x00,0x8F,0x00,0x9C,0x00,0xA9,0x00,0xB6,0x00,0xC3,0x00,0xD0,0x00,0xDD,0x00, 0xEA,0x00,0xF7,0x00,0x04,0x01,0x11,0x01,0x1E,0x01,0x2B,0x01,0x38,0x01,0x45,0x01,0x52,0x01, 0x5F,0x01,0x6C,0x01,0x79,0x01,0x86,0x01,0x93,0x01,0xA0,0x01,0xAD,0x01,0xBA,0x01,0xC7,0x01, 0xD4,0x01,0xE1,0x01,0xEE,0x01,0xFB,0x01,0x08,0x02,0x15,0x02,0x22,0x02,0x2F,0x02,0x3C,0x02, 0x49,0x02,0x56,0x02,0x63,0x02,0x70,0x02,0x7D,0x02,0x8A,0x02,0x97,0x02,0xA4,0x02,0xB1,0x02, 0xBE,0x02,0xCB,0x02,0xD8,0x02,0xE5,0x02,0xF2,0x02,0xFF,0x02,0x0C,0x03,0x19,0x03,0x26,0x03, 0x33,0x03,0x40,0x03,0x4D,0x03,0x5A,0x03,0x67,0x03,0x74,0x03,0x81,0x03,0x8E,0x03,0x9B,0x03, 0xA8,0x03,0xB5,0x03,0xC2,0x03,0xCF,0x03,0xDC,0x03,0xE9,0x03,0xF6,0x03,0x03,0x04,0x10,0x04, 0x1D,0x04,0x2A,0x04,0x37,0x04,0x44,0x04,0x51,0x04,0x5E,0x04,0x6B,0x04,0x78,0x04,0x85,0x04, 0x92,0x04,0x9F,0x04,0xAC,0x04,0xB9,0x04,0xC6,0x04,0xD3,0x04, 7, // 0x20 ' ' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x21 '!' 0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x10,0x00,0x00, 7, // 0x22 '"' 0x28,0x28,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x23 '#' 0x00,0x28,0x28,0x7C,0x28,0x28,0x28,0x7C,0x28,0x28,0x00,0x00, 7, // 0x24 '$' 0x00,0x10,0x38,0x54,0x50,0x38,0x14,0x54,0x38,0x10,0x00,0x00, 7, // 0x25 '%' 0x34,0x54,0x68,0x08,0x10,0x10,0x20,0x2C,0x54,0x58,0x00,0x00, 7, // 0x26 '&' 0x00,0x20,0x50,0x50,0x20,0x54,0x54,0x48,0x34,0x00,0x00,0x00, 7, // 0x27 ''' 0x00,0x10,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x28 '(' 0x08,0x10,0x10,0x20,0x20,0x20,0x20,0x20,0x10,0x10,0x08,0x00, 7, // 0x29 ')' 0x20,0x10,0x10,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x00, 7, // 0x2A '*' 0x00,0x00,0x10,0x54,0x38,0x7C,0x38,0x54,0x10,0x00,0x00,0x00, 7, // 0x2B '+' 0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00,0x00,0x00, 7, // 0x2C ',' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x20,0x40,0x00, 7, // 0x2D '-' 0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x2E '.' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00, 7, // 0x2F '/' 0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x00,0x00, 7, // 0x30 '0' 0x00,0x38,0x44,0x44,0x54,0x54,0x44,0x44,0x38,0x00,0x00,0x00, 7, // 0x31 '1' 0x00,0x10,0x30,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00, 7, // 0x32 '2' 0x00,0x38,0x44,0x44,0x08,0x10,0x20,0x40,0x7C,0x00,0x00,0x00, 7, // 0x33 '3' 0x00,0x38,0x44,0x04,0x38,0x04,0x04,0x44,0x38,0x00,0x00,0x00, 7, // 0x34 '4' 0x00,0x08,0x18,0x28,0x28,0x48,0x7C,0x08,0x08,0x00,0x00,0x00, 7, // 0x35 '5' 0x00,0x7C,0x40,0x78,0x44,0x04,0x04,0x44,0x38,0x00,0x00,0x00, 7, // 0x36 '6' 0x00,0x38,0x44,0x40,0x78,0x44,0x44,0x44,0x38,0x00,0x00,0x00, 7, // 0x37 '7' 0x00,0x7C,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x00,0x00,0x00, 7, // 0x38 '8' 0x00,0x38,0x44,0x44,0x38,0x44,0x44,0x44,0x38,0x00,0x00,0x00, 7, // 0x39 '9' 0x00,0x38,0x44,0x44,0x44,0x3C,0x04,0x44,0x38,0x00,0x00,0x00, 7, // 0x3A ':' 0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x00,0x00,0x00, 7, // 0x3B ';' 0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x20,0x40,0x00, 7, // 0x3C '<' 0x00,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x00,0x00, 7, // 0x3D '=' 0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x00,0x00, 7, // 0x3E '>' 0x00,0x40,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x40,0x00,0x00, 7, // 0x3F '?' 0x00,0x38,0x44,0x04,0x04,0x08,0x10,0x10,0x00,0x10,0x00,0x00, 7, // 0x40 '@' 0x00,0x38,0x44,0x44,0x5C,0x54,0x4C,0x40,0x38,0x00,0x00,0x00, 7, // 0x41 'A' 0x00,0x38,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x00,0x00,0x00, 7, // 0x42 'B' 0x00,0x78,0x44,0x44,0x78,0x44,0x44,0x44,0x78,0x00,0x00,0x00, 7, // 0x43 'C' 0x00,0x38,0x44,0x40,0x40,0x40,0x40,0x44,0x38,0x00,0x00,0x00, 7, // 0x44 'D' 0x00,0x70,0x48,0x44,0x44,0x44,0x44,0x48,0x70,0x00,0x00,0x00, 7, // 0x45 'E' 0x00,0x7C,0x40,0x40,0x78,0x40,0x40,0x40,0x7C,0x00,0x00,0x00, 7, // 0x46 'F' 0x00,0x7C,0x40,0x40,0x78,0x40,0x40,0x40,0x40,0x00,0x00,0x00, 7, // 0x47 'G' 0x00,0x38,0x44,0x40,0x40,0x4C,0x44,0x4C,0x34,0x00,0x00,0x00, 7, // 0x48 'H' 0x00,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0x00,0x00,0x00, 7, // 0x49 'I' 0x00,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00, 7, // 0x4A 'J' 0x00,0x1C,0x08,0x08,0x08,0x08,0x48,0x48,0x30,0x00,0x00,0x00, 7, // 0x4B 'K' 0x00,0x44,0x48,0x50,0x60,0x60,0x50,0x48,0x44,0x00,0x00,0x00, 7, // 0x4C 'L' 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7C,0x00,0x00,0x00, 7, // 0x4D 'M' 0x00,0x44,0x6C,0x54,0x54,0x44,0x44,0x44,0x44,0x00,0x00,0x00, 7, // 0x4E 'N' 0x00,0x44,0x64,0x64,0x54,0x54,0x4C,0x4C,0x44,0x00,0x00,0x00, 7, // 0x4F 'O' 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, 7, // 0x50 'P' 0x00,0x78,0x44,0x44,0x44,0x78,0x40,0x40,0x40,0x00,0x00,0x00, 7, // 0x51 'Q' 0x00,0x38,0x44,0x44,0x44,0x44,0x54,0x48,0x34,0x00,0x00,0x00, 7, // 0x52 'R' 0x00,0x78,0x44,0x44,0x44,0x78,0x48,0x44,0x44,0x00,0x00,0x00, 7, // 0x53 'S' 0x00,0x38,0x44,0x40,0x38,0x04,0x44,0x44,0x38,0x00,0x00,0x00, 7, // 0x54 'T' 0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00, 7, // 0x55 'U' 0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, 7, // 0x56 'V' 0x00,0x44,0x44,0x44,0x28,0x28,0x28,0x10,0x10,0x00,0x00,0x00, 7, // 0x57 'W' 0x00,0x44,0x44,0x44,0x44,0x44,0x54,0x54,0x28,0x00,0x00,0x00, 7, // 0x58 'X' 0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x44,0x00,0x00,0x00, 7, // 0x59 'Y' 0x00,0x44,0x44,0x44,0x28,0x10,0x10,0x10,0x10,0x00,0x00,0x00, 7, // 0x5A 'Z' 0x00,0x7C,0x04,0x08,0x10,0x20,0x40,0x40,0x7C,0x00,0x00,0x00, 7, // 0x5B '[' 0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x38,0x00, 7, // 0x5C '\' 0x00,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x00, 7, // 0x5D ']' 0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x38,0x00, 7, // 0x5E '^' 0x00,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x5F '_' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00, 7, // 0x60 '`' 0x00,0x20,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x61 'a' 0x00,0x00,0x00,0x38,0x04,0x3C,0x44,0x44,0x3C,0x00,0x00,0x00, 7, // 0x62 'b' 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x78,0x00,0x00,0x00, 7, // 0x63 'c' 0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x44,0x38,0x00,0x00,0x00, 7, // 0x64 'd' 0x00,0x04,0x04,0x3C,0x44,0x44,0x44,0x44,0x3C,0x00,0x00,0x00, 7, // 0x65 'e' 0x00,0x00,0x00,0x38,0x44,0x7C,0x40,0x44,0x38,0x00,0x00,0x00, 7, // 0x66 'f' 0x00,0x0C,0x10,0x38,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00, 7, // 0x67 'g' 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x3C,0x04,0x44,0x38, 7, // 0x68 'h' 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x00,0x00,0x00, 7, // 0x69 'i' 0x00,0x10,0x00,0x30,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00, 7, // 0x6A 'j' 0x00,0x08,0x00,0x18,0x08,0x08,0x08,0x08,0x08,0x48,0x48,0x30, 7, // 0x6B 'k' 0x00,0x40,0x40,0x4C,0x50,0x60,0x50,0x48,0x44,0x00,0x00,0x00, 7, // 0x6C 'l' 0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00, 7, // 0x6D 'm' 0x00,0x00,0x00,0x68,0x54,0x54,0x44,0x44,0x44,0x00,0x00,0x00, 7, // 0x6E 'n' 0x00,0x00,0x00,0x58,0x64,0x44,0x44,0x44,0x44,0x00,0x00,0x00, 7, // 0x6F 'o' 0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, 7, // 0x70 'p' 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x40,0x40,0x40, 7, // 0x71 'q' 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x3C,0x04,0x04,0x04, 7, // 0x72 'r' 0x00,0x00,0x00,0x58,0x24,0x20,0x20,0x20,0x70,0x00,0x00,0x00, 7, // 0x73 's' 0x00,0x00,0x00,0x38,0x44,0x30,0x08,0x44,0x38,0x00,0x00,0x00, 7, // 0x74 't' 0x00,0x20,0x20,0x70,0x20,0x20,0x20,0x24,0x18,0x00,0x00,0x00, 7, // 0x75 'u' 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x4C,0x34,0x00,0x00,0x00, 7, // 0x76 'v' 0x00,0x00,0x00,0x44,0x44,0x28,0x28,0x10,0x10,0x00,0x00,0x00, 7, // 0x77 'w' 0x00,0x00,0x00,0x44,0x44,0x44,0x54,0x54,0x28,0x00,0x00,0x00, 7, // 0x78 'x' 0x00,0x00,0x00,0x44,0x28,0x10,0x28,0x44,0x44,0x00,0x00,0x00, 7, // 0x79 'y' 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x3C,0x04,0x08,0x70, 7, // 0x7A 'z' 0x00,0x00,0x00,0x7C,0x08,0x10,0x20,0x40,0x7C,0x00,0x00,0x00, 7, // 0x7B '{' 0x18,0x20,0x20,0x20,0x20,0xC0,0x20,0x20,0x20,0x20,0x18,0x00, 7, // 0x7C '|' 0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00, 7, // 0x7D '}' 0x60,0x10,0x10,0x10,0x10,0x0C,0x10,0x10,0x10,0x10,0x60,0x00, 7, // 0x7E '~' 0x00,0x24,0x54,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x7F '' 0x00,0x10,0x38,0x6C,0x44,0x44,0x7C,0x00,0x00,0x00,0x00,0x00, 0 }; const int8u verdana12[] = { 12, 3, 32, 128-32, 0x00,0x00,0x0D,0x00,0x1A,0x00,0x27,0x00,0x34,0x00,0x41,0x00,0x5A,0x00,0x67,0x00,0x74,0x00, 0x81,0x00,0x8E,0x00,0x9B,0x00,0xA8,0x00,0xB5,0x00,0xC2,0x00,0xCF,0x00,0xDC,0x00,0xE9,0x00, 0xF6,0x00,0x03,0x01,0x10,0x01,0x1D,0x01,0x2A,0x01,0x37,0x01,0x44,0x01,0x51,0x01,0x5E,0x01, 0x6B,0x01,0x78,0x01,0x85,0x01,0x92,0x01,0x9F,0x01,0xAC,0x01,0xC5,0x01,0xD2,0x01,0xDF,0x01, 0xEC,0x01,0xF9,0x01,0x06,0x02,0x13,0x02,0x20,0x02,0x2D,0x02,0x3A,0x02,0x47,0x02,0x54,0x02, 0x61,0x02,0x7A,0x02,0x87,0x02,0xA0,0x02,0xAD,0x02,0xC6,0x02,0xD3,0x02,0xE0,0x02,0xED,0x02, 0xFA,0x02,0x07,0x03,0x20,0x03,0x2D,0x03,0x3A,0x03,0x47,0x03,0x54,0x03,0x61,0x03,0x6E,0x03, 0x7B,0x03,0x88,0x03,0x95,0x03,0xA2,0x03,0xAF,0x03,0xBC,0x03,0xC9,0x03,0xD6,0x03,0xE3,0x03, 0xF0,0x03,0xFD,0x03,0x0A,0x04,0x17,0x04,0x24,0x04,0x31,0x04,0x4A,0x04,0x57,0x04,0x64,0x04, 0x71,0x04,0x7E,0x04,0x8B,0x04,0x98,0x04,0xA5,0x04,0xB2,0x04,0xBF,0x04,0xCC,0x04,0xD9,0x04, 0xE6,0x04,0xF3,0x04,0x00,0x05,0x0D,0x05,0x1A,0x05,0x27,0x05, 3, // 0x20 ' ' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x21 '!' 0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00, 5, // 0x22 '"' 0x00,0x00,0x50,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x23 '#' 0x00,0x00,0x00,0x00,0x28,0x7C,0x28,0x7C,0x28,0x00,0x00,0x00, 7, // 0x24 '$' 0x00,0x00,0x10,0x10,0x3C,0x50,0x30,0x18,0x14,0x78,0x10,0x10, 11, // 0x25 '%' 0x00,0x00,0x00,0x00,0x00,0x00,0x31,0x00,0x4A,0x00,0x4A,0x00,0x35,0x80,0x0A,0x40,0x0A,0x40,0x11,0x80,0x00,0x00,0x00,0x00, 7, // 0x26 '&' 0x00,0x00,0x00,0x30,0x48,0x48,0x32,0x4A,0x44,0x3A,0x00,0x00, 3, // 0x27 ''' 0x00,0x00,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 4, // 0x28 '(' 0x00,0x00,0x10,0x20,0x40,0x40,0x40,0x40,0x40,0x40,0x20,0x10, 4, // 0x29 ')' 0x00,0x00,0x80,0x40,0x20,0x20,0x20,0x20,0x20,0x20,0x40,0x80, 7, // 0x2A '*' 0x00,0x10,0x54,0x38,0x54,0x10,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x2B '+' 0x00,0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00,0x00, 3, // 0x2C ',' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x80,0x00, 5, // 0x2D '-' 0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00, 3, // 0x2E '.' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x00,0x00, 4, // 0x2F '/' 0x00,0x00,0x10,0x10,0x20,0x20,0x40,0x40,0x40,0x80,0x80,0x00, 7, // 0x30 '0' 0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, 7, // 0x31 '1' 0x00,0x00,0x00,0x10,0x30,0x10,0x10,0x10,0x10,0x38,0x00,0x00, 7, // 0x32 '2' 0x00,0x00,0x00,0x38,0x44,0x04,0x08,0x10,0x20,0x7C,0x00,0x00, 7, // 0x33 '3' 0x00,0x00,0x00,0x38,0x44,0x04,0x18,0x04,0x44,0x38,0x00,0x00, 7, // 0x34 '4' 0x00,0x00,0x00,0x08,0x18,0x28,0x48,0x7C,0x08,0x08,0x00,0x00, 7, // 0x35 '5' 0x00,0x00,0x00,0x7C,0x40,0x78,0x04,0x04,0x44,0x38,0x00,0x00, 7, // 0x36 '6' 0x00,0x00,0x00,0x18,0x20,0x40,0x78,0x44,0x44,0x38,0x00,0x00, 7, // 0x37 '7' 0x00,0x00,0x00,0x7C,0x04,0x08,0x08,0x10,0x10,0x10,0x00,0x00, 7, // 0x38 '8' 0x00,0x00,0x00,0x38,0x44,0x44,0x38,0x44,0x44,0x38,0x00,0x00, 7, // 0x39 '9' 0x00,0x00,0x00,0x38,0x44,0x44,0x3C,0x04,0x08,0x30,0x00,0x00, 4, // 0x3A ':' 0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x00,0x40,0x40,0x00,0x00, 4, // 0x3B ';' 0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x00,0x40,0x40,0x80,0x00, 7, // 0x3C '<' 0x00,0x00,0x00,0x00,0x04,0x18,0x60,0x18,0x04,0x00,0x00,0x00, 7, // 0x3D '=' 0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x7C,0x00,0x00,0x00,0x00, 7, // 0x3E '>' 0x00,0x00,0x00,0x00,0x40,0x30,0x0C,0x30,0x40,0x00,0x00,0x00, 6, // 0x3F '?' 0x00,0x00,0x00,0x70,0x08,0x08,0x10,0x20,0x00,0x20,0x00,0x00, 10, // 0x40 '@' 0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x20,0x80,0x4E,0x80,0x52,0x80,0x52,0x80,0x4D,0x00,0x20,0x00,0x1F,0x00,0x00,0x00, 8, // 0x41 'A' 0x00,0x00,0x00,0x18,0x18,0x24,0x24,0x7E,0x42,0x42,0x00,0x00, 7, // 0x42 'B' 0x00,0x00,0x00,0x70,0x48,0x48,0x78,0x44,0x44,0x78,0x00,0x00, 8, // 0x43 'C' 0x00,0x00,0x00,0x1C,0x22,0x40,0x40,0x40,0x22,0x1C,0x00,0x00, 8, // 0x44 'D' 0x00,0x00,0x00,0x78,0x44,0x42,0x42,0x42,0x44,0x78,0x00,0x00, 7, // 0x45 'E' 0x00,0x00,0x00,0x7C,0x40,0x40,0x78,0x40,0x40,0x7C,0x00,0x00, 6, // 0x46 'F' 0x00,0x00,0x00,0x7C,0x40,0x40,0x78,0x40,0x40,0x40,0x00,0x00, 8, // 0x47 'G' 0x00,0x00,0x00,0x1C,0x22,0x40,0x4E,0x42,0x22,0x1C,0x00,0x00, 8, // 0x48 'H' 0x00,0x00,0x00,0x42,0x42,0x42,0x7E,0x42,0x42,0x42,0x00,0x00, 5, // 0x49 'I' 0x00,0x00,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, 5, // 0x4A 'J' 0x00,0x00,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0xE0,0x00,0x00, 7, // 0x4B 'K' 0x00,0x00,0x00,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x00,0x00, 6, // 0x4C 'L' 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x7C,0x00,0x00, 9, // 0x4D 'M' 0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x55,0x00,0x55,0x00,0x49,0x00,0x49,0x00,0x41,0x00,0x00,0x00,0x00,0x00, 8, // 0x4E 'N' 0x00,0x00,0x00,0x42,0x62,0x52,0x4A,0x46,0x42,0x42,0x00,0x00, 9, // 0x4F 'O' 0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x22,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00, 7, // 0x50 'P' 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x78,0x40,0x40,0x00,0x00, 9, // 0x51 'Q' 0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x22,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x1C,0x00,0x04,0x00,0x03,0x00, 7, // 0x52 'R' 0x00,0x00,0x00,0x78,0x44,0x44,0x78,0x50,0x48,0x44,0x00,0x00, 7, // 0x53 'S' 0x00,0x00,0x00,0x38,0x44,0x40,0x38,0x04,0x44,0x38,0x00,0x00, 7, // 0x54 'T' 0x00,0x00,0x00,0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, 8, // 0x55 'U' 0x00,0x00,0x00,0x42,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00, 8, // 0x56 'V' 0x00,0x00,0x00,0x42,0x42,0x42,0x24,0x24,0x18,0x18,0x00,0x00, 9, // 0x57 'W' 0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x49,0x00,0x49,0x00,0x55,0x00,0x55,0x00,0x22,0x00,0x22,0x00,0x00,0x00,0x00,0x00, 7, // 0x58 'X' 0x00,0x00,0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x00,0x00, 7, // 0x59 'Y' 0x00,0x00,0x00,0x44,0x44,0x28,0x28,0x10,0x10,0x10,0x00,0x00, 7, // 0x5A 'Z' 0x00,0x00,0x00,0x7C,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,0x00, 4, // 0x5B '[' 0x00,0x00,0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x60, 4, // 0x5C '\' 0x00,0x00,0x80,0x80,0x40,0x40,0x40,0x20,0x20,0x10,0x10,0x00, 4, // 0x5D ']' 0x00,0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x60, 7, // 0x5E '^' 0x00,0x00,0x00,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x5F '_' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC, 6, // 0x60 '`' 0x00,0x00,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x61 'a' 0x00,0x00,0x00,0x00,0x00,0x30,0x08,0x38,0x48,0x38,0x00,0x00, 6, // 0x62 'b' 0x00,0x00,0x40,0x40,0x40,0x70,0x48,0x48,0x48,0x70,0x00,0x00, 6, // 0x63 'c' 0x00,0x00,0x00,0x00,0x00,0x38,0x40,0x40,0x40,0x38,0x00,0x00, 6, // 0x64 'd' 0x00,0x00,0x08,0x08,0x08,0x38,0x48,0x48,0x48,0x38,0x00,0x00, 6, // 0x65 'e' 0x00,0x00,0x00,0x00,0x00,0x30,0x48,0x78,0x40,0x38,0x00,0x00, 4, // 0x66 'f' 0x00,0x00,0x30,0x40,0x40,0xE0,0x40,0x40,0x40,0x40,0x00,0x00, 6, // 0x67 'g' 0x00,0x00,0x00,0x00,0x00,0x38,0x48,0x48,0x48,0x38,0x08,0x30, 6, // 0x68 'h' 0x00,0x00,0x40,0x40,0x40,0x70,0x48,0x48,0x48,0x48,0x00,0x00, 3, // 0x69 'i' 0x00,0x00,0x00,0x40,0x00,0x40,0x40,0x40,0x40,0x40,0x00,0x00, 3, // 0x6A 'j' 0x00,0x00,0x00,0x40,0x00,0xC0,0x40,0x40,0x40,0x40,0x40,0x80, 6, // 0x6B 'k' 0x00,0x00,0x40,0x40,0x40,0x48,0x50,0x60,0x50,0x48,0x00,0x00, 3, // 0x6C 'l' 0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00, 9, // 0x6D 'm' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x76,0x00,0x49,0x00,0x49,0x00,0x49,0x00,0x49,0x00,0x00,0x00,0x00,0x00, 6, // 0x6E 'n' 0x00,0x00,0x00,0x00,0x00,0x70,0x48,0x48,0x48,0x48,0x00,0x00, 6, // 0x6F 'o' 0x00,0x00,0x00,0x00,0x00,0x30,0x48,0x48,0x48,0x30,0x00,0x00, 6, // 0x70 'p' 0x00,0x00,0x00,0x00,0x00,0x70,0x48,0x48,0x48,0x70,0x40,0x40, 6, // 0x71 'q' 0x00,0x00,0x00,0x00,0x00,0x38,0x48,0x48,0x48,0x38,0x08,0x08, 4, // 0x72 'r' 0x00,0x00,0x00,0x00,0x00,0x50,0x60,0x40,0x40,0x40,0x00,0x00, 6, // 0x73 's' 0x00,0x00,0x00,0x00,0x00,0x38,0x40,0x30,0x08,0x70,0x00,0x00, 4, // 0x74 't' 0x00,0x00,0x00,0x00,0x40,0xF0,0x40,0x40,0x40,0x30,0x00,0x00, 6, // 0x75 'u' 0x00,0x00,0x00,0x00,0x00,0x48,0x48,0x48,0x48,0x38,0x00,0x00, 6, // 0x76 'v' 0x00,0x00,0x00,0x00,0x00,0x48,0x48,0x48,0x30,0x30,0x00,0x00, 7, // 0x77 'w' 0x00,0x00,0x00,0x00,0x00,0x44,0x54,0x54,0x28,0x28,0x00,0x00, 6, // 0x78 'x' 0x00,0x00,0x00,0x00,0x00,0x48,0x48,0x30,0x48,0x48,0x00,0x00, 6, // 0x79 'y' 0x00,0x00,0x00,0x00,0x00,0x48,0x48,0x48,0x30,0x10,0x20,0x20, 5, // 0x7A 'z' 0x00,0x00,0x00,0x00,0x00,0x70,0x10,0x20,0x40,0x70,0x00,0x00, 6, // 0x7B '{' 0x00,0x00,0x18,0x20,0x20,0x20,0x20,0xC0,0x20,0x20,0x20,0x18, 5, // 0x7C '|' 0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, 6, // 0x7D '}' 0x00,0x00,0x60,0x10,0x10,0x10,0x10,0x0C,0x10,0x10,0x10,0x60, 7, // 0x7E '~' 0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x58,0x00,0x00,0x00,0x00, 9, // 0x7F '' 0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x7F,0x00,0x00,0x00,0x00,0x00, 0 }; const int8u verdana12_bold[] = { 12, 3, 32, 128-32, 0x00,0x00,0x0D,0x00,0x1A,0x00,0x27,0x00,0x34,0x00,0x41,0x00,0x5A,0x00,0x67,0x00,0x74,0x00, 0x81,0x00,0x8E,0x00,0x9B,0x00,0xA8,0x00,0xB5,0x00,0xC2,0x00,0xCF,0x00,0xDC,0x00,0xE9,0x00, 0xF6,0x00,0x03,0x01,0x10,0x01,0x1D,0x01,0x2A,0x01,0x37,0x01,0x44,0x01,0x51,0x01,0x5E,0x01, 0x6B,0x01,0x78,0x01,0x85,0x01,0x92,0x01,0x9F,0x01,0xAC,0x01,0xC5,0x01,0xD2,0x01,0xDF,0x01, 0xEC,0x01,0xF9,0x01,0x06,0x02,0x13,0x02,0x20,0x02,0x2D,0x02,0x3A,0x02,0x47,0x02,0x54,0x02, 0x61,0x02,0x6E,0x02,0x7B,0x02,0x88,0x02,0x95,0x02,0xA2,0x02,0xAF,0x02,0xBC,0x02,0xC9,0x02, 0xD6,0x02,0xE3,0x02,0xFC,0x02,0x09,0x03,0x16,0x03,0x23,0x03,0x30,0x03,0x3D,0x03,0x4A,0x03, 0x57,0x03,0x64,0x03,0x71,0x03,0x7E,0x03,0x8B,0x03,0x98,0x03,0xA5,0x03,0xB2,0x03,0xBF,0x03, 0xCC,0x03,0xD9,0x03,0xE6,0x03,0xF3,0x03,0x00,0x04,0x0D,0x04,0x26,0x04,0x33,0x04,0x40,0x04, 0x4D,0x04,0x5A,0x04,0x67,0x04,0x74,0x04,0x81,0x04,0x8E,0x04,0x9B,0x04,0xB4,0x04,0xC1,0x04, 0xCE,0x04,0xDB,0x04,0xE8,0x04,0xF5,0x04,0x02,0x05,0x0F,0x05, 3, // 0x20 ' ' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 4, // 0x21 '!' 0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x00,0x60,0x00,0x00, 5, // 0x22 '"' 0x00,0x00,0xD8,0xD8,0xD8,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x23 '#' 0x00,0x00,0x00,0x14,0x14,0x7E,0x28,0xFC,0x50,0x50,0x00,0x00, 6, // 0x24 '$' 0x00,0x00,0x20,0x20,0x70,0xE8,0xE0,0x38,0xB8,0x70,0x20,0x20, 11, // 0x25 '%' 0x00,0x00,0x00,0x00,0x00,0x00,0x62,0x00,0x94,0x00,0x94,0x00,0x69,0x80,0x0A,0x40,0x0A,0x40,0x11,0x80,0x00,0x00,0x00,0x00, 8, // 0x26 '&' 0x00,0x00,0x00,0x70,0xD8,0xD8,0x76,0xDC,0xCC,0x76,0x00,0x00, 3, // 0x27 ''' 0x00,0x00,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x28 '(' 0x00,0x00,0x30,0x60,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x60,0x30, 5, // 0x29 ')' 0x00,0x00,0xC0,0x60,0x30,0x30,0x30,0x30,0x30,0x30,0x60,0xC0, 6, // 0x2A '*' 0x00,0x00,0x20,0xA8,0x70,0xA8,0x20,0x00,0x00,0x00,0x00,0x00, 8, // 0x2B '+' 0x00,0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00,0x00, 3, // 0x2C ',' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0x80,0x00, 4, // 0x2D '-' 0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x00,0x00, 3, // 0x2E '.' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0x00,0x00, 6, // 0x2F '/' 0x00,0x00,0x08,0x08,0x10,0x10,0x20,0x40,0x40,0x80,0x80,0x00, 6, // 0x30 '0' 0x00,0x00,0x00,0x70,0xD8,0xD8,0xD8,0xD8,0xD8,0x70,0x00,0x00, 6, // 0x31 '1' 0x00,0x00,0x00,0x30,0x70,0x30,0x30,0x30,0x30,0x78,0x00,0x00, 6, // 0x32 '2' 0x00,0x00,0x00,0x70,0x98,0x18,0x30,0x60,0xC0,0xF8,0x00,0x00, 6, // 0x33 '3' 0x00,0x00,0x00,0x70,0x98,0x18,0x70,0x18,0x98,0x70,0x00,0x00, 6, // 0x34 '4' 0x00,0x00,0x00,0x18,0x38,0x58,0x98,0xFC,0x18,0x18,0x00,0x00, 6, // 0x35 '5' 0x00,0x00,0x00,0xF8,0xC0,0xF0,0x18,0x18,0x98,0x70,0x00,0x00, 6, // 0x36 '6' 0x00,0x00,0x00,0x70,0xC0,0xF0,0xD8,0xD8,0xD8,0x70,0x00,0x00, 6, // 0x37 '7' 0x00,0x00,0x00,0xF8,0x18,0x30,0x30,0x60,0x60,0xC0,0x00,0x00, 6, // 0x38 '8' 0x00,0x00,0x00,0x70,0xD8,0xD8,0x70,0xD8,0xD8,0x70,0x00,0x00, 6, // 0x39 '9' 0x00,0x00,0x00,0x70,0xD8,0xD8,0xD8,0x78,0x18,0x70,0x00,0x00, 4, // 0x3A ':' 0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x60,0x60,0x00,0x00, 4, // 0x3B ';' 0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x60,0x60,0x40,0x00, 8, // 0x3C '<' 0x00,0x00,0x00,0x00,0x04,0x18,0x60,0x60,0x18,0x04,0x00,0x00, 8, // 0x3D '=' 0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x7C,0x00,0x00,0x00,0x00, 8, // 0x3E '>' 0x00,0x00,0x00,0x00,0x40,0x30,0x0C,0x0C,0x30,0x40,0x00,0x00, 6, // 0x3F '?' 0x00,0x00,0x00,0xF0,0x18,0x18,0x30,0x60,0x00,0x60,0x00,0x00, 9, // 0x40 '@' 0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x42,0x00,0x9D,0x00,0xA5,0x00,0xA5,0x00,0x9E,0x00,0x40,0x00,0x3C,0x00,0x00,0x00, 8, // 0x41 'A' 0x00,0x00,0x00,0x38,0x38,0x6C,0x6C,0x7C,0xC6,0xC6,0x00,0x00, 7, // 0x42 'B' 0x00,0x00,0x00,0xF8,0xCC,0xCC,0xF8,0xCC,0xCC,0xF8,0x00,0x00, 6, // 0x43 'C' 0x00,0x00,0x00,0x70,0xC8,0xC0,0xC0,0xC0,0xC8,0x70,0x00,0x00, 7, // 0x44 'D' 0x00,0x00,0x00,0xF8,0xCC,0xCC,0xCC,0xCC,0xCC,0xF8,0x00,0x00, 6, // 0x45 'E' 0x00,0x00,0x00,0xF8,0xC0,0xC0,0xF8,0xC0,0xC0,0xF8,0x00,0x00, 6, // 0x46 'F' 0x00,0x00,0x00,0xF8,0xC0,0xC0,0xF8,0xC0,0xC0,0xC0,0x00,0x00, 7, // 0x47 'G' 0x00,0x00,0x00,0x78,0xC4,0xC0,0xC0,0xDC,0xCC,0x7C,0x00,0x00, 7, // 0x48 'H' 0x00,0x00,0x00,0xCC,0xCC,0xCC,0xFC,0xCC,0xCC,0xCC,0x00,0x00, 5, // 0x49 'I' 0x00,0x00,0x00,0xF0,0x60,0x60,0x60,0x60,0x60,0xF0,0x00,0x00, 5, // 0x4A 'J' 0x00,0x00,0x00,0x70,0x30,0x30,0x30,0x30,0x30,0xE0,0x00,0x00, 7, // 0x4B 'K' 0x00,0x00,0x00,0xCC,0xD8,0xF0,0xE0,0xF0,0xD8,0xCC,0x00,0x00, 6, // 0x4C 'L' 0x00,0x00,0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xF8,0x00,0x00, 8, // 0x4D 'M' 0x00,0x00,0x00,0x82,0xC6,0xEE,0xB6,0xB6,0x86,0x86,0x00,0x00, 7, // 0x4E 'N' 0x00,0x00,0x00,0x84,0xC4,0xE4,0xB4,0x9C,0x8C,0x84,0x00,0x00, 8, // 0x4F 'O' 0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00, 7, // 0x50 'P' 0x00,0x00,0x00,0xF8,0xCC,0xCC,0xCC,0xF8,0xC0,0xC0,0x00,0x00, 8, // 0x51 'Q' 0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x18,0x0E, 7, // 0x52 'R' 0x00,0x00,0x00,0xF8,0xCC,0xCC,0xF8,0xD8,0xCC,0xC6,0x00,0x00, 6, // 0x53 'S' 0x00,0x00,0x00,0x70,0xC8,0xC0,0x70,0x18,0x98,0x70,0x00,0x00, 6, // 0x54 'T' 0x00,0x00,0x00,0xFC,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00, 7, // 0x55 'U' 0x00,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x78,0x00,0x00, 7, // 0x56 'V' 0x00,0x00,0x00,0xCC,0xCC,0x78,0x78,0x78,0x30,0x30,0x00,0x00, 11, // 0x57 'W' 0x00,0x00,0x00,0x00,0x00,0x00,0xCC,0xC0,0xCC,0xC0,0x6D,0x80,0x6D,0x80,0x73,0x80,0x33,0x00,0x33,0x00,0x00,0x00,0x00,0x00, 7, // 0x58 'X' 0x00,0x00,0x00,0xCC,0xCC,0x78,0x30,0x78,0xCC,0xCC,0x00,0x00, 7, // 0x59 'Y' 0x00,0x00,0x00,0xCC,0xCC,0x78,0x30,0x30,0x30,0x30,0x00,0x00, 6, // 0x5A 'Z' 0x00,0x00,0x00,0xF8,0x18,0x30,0x60,0xC0,0xC0,0xF8,0x00,0x00, 5, // 0x5B '[' 0x00,0x00,0x70,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x70, 6, // 0x5C '\' 0x00,0x00,0x80,0x80,0x40,0x40,0x20,0x10,0x10,0x08,0x08,0x00, 5, // 0x5D ']' 0x00,0x00,0x70,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x70, 8, // 0x5E '^' 0x00,0x00,0x00,0x18,0x3C,0x66,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x5F '_' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC, 6, // 0x60 '`' 0x00,0x00,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x61 'a' 0x00,0x00,0x00,0x00,0x00,0x70,0x18,0x78,0xD8,0x78,0x00,0x00, 6, // 0x62 'b' 0x00,0x00,0xC0,0xC0,0xC0,0xF0,0xD8,0xD8,0xD8,0xF0,0x00,0x00, 5, // 0x63 'c' 0x00,0x00,0x00,0x00,0x00,0x70,0xC0,0xC0,0xC0,0x70,0x00,0x00, 6, // 0x64 'd' 0x00,0x00,0x18,0x18,0x18,0x78,0xD8,0xD8,0xD8,0x78,0x00,0x00, 6, // 0x65 'e' 0x00,0x00,0x00,0x00,0x00,0x70,0xD8,0xF8,0xC0,0x78,0x00,0x00, 5, // 0x66 'f' 0x00,0x00,0x38,0x60,0x60,0xF8,0x60,0x60,0x60,0x60,0x00,0x00, 6, // 0x67 'g' 0x00,0x00,0x00,0x00,0x00,0x78,0xD8,0xD8,0xD8,0x78,0x18,0x70, 6, // 0x68 'h' 0x00,0x00,0xC0,0xC0,0xC0,0xF0,0xD8,0xD8,0xD8,0xD8,0x00,0x00, 3, // 0x69 'i' 0x00,0x00,0x00,0xC0,0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00, 4, // 0x6A 'j' 0x00,0x00,0x00,0x60,0x00,0xE0,0x60,0x60,0x60,0x60,0x60,0xC0, 6, // 0x6B 'k' 0x00,0x00,0xC0,0xC0,0xC0,0xD8,0xD8,0xF0,0xD8,0xD8,0x00,0x00, 3, // 0x6C 'l' 0x00,0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00, 9, // 0x6D 'm' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF6,0x00,0xDB,0x00,0xDB,0x00,0xDB,0x00,0xDB,0x00,0x00,0x00,0x00,0x00, 6, // 0x6E 'n' 0x00,0x00,0x00,0x00,0x00,0xF0,0xD8,0xD8,0xD8,0xD8,0x00,0x00, 6, // 0x6F 'o' 0x00,0x00,0x00,0x00,0x00,0x70,0xD8,0xD8,0xD8,0x70,0x00,0x00, 6, // 0x70 'p' 0x00,0x00,0x00,0x00,0x00,0xF0,0xD8,0xD8,0xD8,0xF0,0xC0,0xC0, 6, // 0x71 'q' 0x00,0x00,0x00,0x00,0x00,0x78,0xD8,0xD8,0xD8,0x78,0x18,0x18, 4, // 0x72 'r' 0x00,0x00,0x00,0x00,0x00,0xD0,0xE0,0xC0,0xC0,0xC0,0x00,0x00, 5, // 0x73 's' 0x00,0x00,0x00,0x00,0x00,0x70,0xC0,0xF0,0x30,0xE0,0x00,0x00, 5, // 0x74 't' 0x00,0x00,0x00,0x60,0x60,0xF8,0x60,0x60,0x60,0x38,0x00,0x00, 6, // 0x75 'u' 0x00,0x00,0x00,0x00,0x00,0xD8,0xD8,0xD8,0xD8,0x78,0x00,0x00, 6, // 0x76 'v' 0x00,0x00,0x00,0x00,0x00,0xD8,0xD8,0xD8,0x70,0x70,0x00,0x00, 9, // 0x77 'w' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xDB,0x00,0xDB,0x00,0xDB,0x00,0x66,0x00,0x66,0x00,0x00,0x00,0x00,0x00, 6, // 0x78 'x' 0x00,0x00,0x00,0x00,0x00,0xD8,0xD8,0x70,0xD8,0xD8,0x00,0x00, 6, // 0x79 'y' 0x00,0x00,0x00,0x00,0x00,0xD8,0xD8,0xD8,0x70,0x70,0x30,0x60, 5, // 0x7A 'z' 0x00,0x00,0x00,0x00,0x00,0xF0,0x30,0x60,0xC0,0xF0,0x00,0x00, 6, // 0x7B '{' 0x00,0x00,0x18,0x30,0x30,0x30,0xE0,0x30,0x30,0x30,0x30,0x18, 5, // 0x7C '|' 0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, 6, // 0x7D '}' 0x00,0x00,0xC0,0x60,0x60,0x60,0x38,0x60,0x60,0x60,0x60,0xC0, 8, // 0x7E '~' 0x00,0x00,0x00,0x00,0x00,0x00,0x62,0x92,0x8C,0x00,0x00,0x00, 9, // 0x7F '' 0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x7F,0x00,0x00,0x00,0x00,0x00, 0 }; const int8u verdana13[] = { 13, 3, 32, 128-32, 0x00,0x00,0x0E,0x00,0x1C,0x00,0x2A,0x00,0x45,0x00,0x53,0x00,0x6E,0x00,0x7C,0x00,0x8A,0x00, 0x98,0x00,0xA6,0x00,0xB4,0x00,0xCF,0x00,0xDD,0x00,0xEB,0x00,0xF9,0x00,0x07,0x01,0x15,0x01, 0x23,0x01,0x31,0x01,0x3F,0x01,0x4D,0x01,0x5B,0x01,0x69,0x01,0x77,0x01,0x85,0x01,0x93,0x01, 0xA1,0x01,0xAF,0x01,0xCA,0x01,0xE5,0x01,0x00,0x02,0x0E,0x02,0x29,0x02,0x37,0x02,0x45,0x02, 0x60,0x02,0x7B,0x02,0x89,0x02,0x97,0x02,0xB2,0x02,0xC0,0x02,0xCE,0x02,0xDC,0x02,0xEA,0x02, 0xF8,0x02,0x13,0x03,0x21,0x03,0x3C,0x03,0x4A,0x03,0x65,0x03,0x73,0x03,0x81,0x03,0x8F,0x03, 0x9D,0x03,0xAB,0x03,0xC6,0x03,0xD4,0x03,0xE2,0x03,0xF0,0x03,0xFE,0x03,0x0C,0x04,0x1A,0x04, 0x35,0x04,0x43,0x04,0x51,0x04,0x5F,0x04,0x6D,0x04,0x7B,0x04,0x89,0x04,0x97,0x04,0xA5,0x04, 0xB3,0x04,0xC1,0x04,0xCF,0x04,0xDD,0x04,0xEB,0x04,0xF9,0x04,0x14,0x05,0x22,0x05,0x30,0x05, 0x3E,0x05,0x4C,0x05,0x5A,0x05,0x68,0x05,0x76,0x05,0x84,0x05,0x92,0x05,0xAD,0x05,0xBB,0x05, 0xC9,0x05,0xD7,0x05,0xE5,0x05,0xF3,0x05,0x01,0x06,0x1C,0x06, 4, // 0x20 ' ' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 4, // 0x21 '!' 0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00, 5, // 0x22 '"' 0x00,0x00,0x50,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x23 '#' 0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x00,0x0A,0x00,0x3F,0x00,0x14,0x00,0x14,0x00,0x7E,0x00,0x28,0x00,0x28,0x00,0x00,0x00,0x00,0x00, 7, // 0x24 '$' 0x00,0x00,0x10,0x10,0x3C,0x50,0x50,0x38,0x14,0x14,0x78,0x10,0x10, 12, // 0x25 '%' 0x00,0x00,0x00,0x00,0x00,0x00,0x31,0x00,0x49,0x00,0x4A,0x00,0x32,0x00,0x04,0xC0,0x05,0x20,0x09,0x20,0x08,0xC0,0x00,0x00,0x00,0x00, 8, // 0x26 '&' 0x00,0x00,0x00,0x30,0x48,0x48,0x32,0x4A,0x44,0x46,0x39,0x00,0x00, 3, // 0x27 ''' 0x00,0x00,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x28 '(' 0x00,0x00,0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x10, 5, // 0x29 ')' 0x00,0x00,0x40,0x20,0x20,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x40, 7, // 0x2A '*' 0x00,0x00,0x10,0x54,0x38,0x54,0x10,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x2B '+' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x7F,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00, 4, // 0x2C ',' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x40, 5, // 0x2D '-' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00, 4, // 0x2E '.' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00, 5, // 0x2F '/' 0x00,0x00,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x80,0x00, 7, // 0x30 '0' 0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, 7, // 0x31 '1' 0x00,0x00,0x00,0x10,0x70,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00, 7, // 0x32 '2' 0x00,0x00,0x00,0x38,0x44,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,0x00, 7, // 0x33 '3' 0x00,0x00,0x00,0x38,0x44,0x04,0x18,0x04,0x04,0x44,0x38,0x00,0x00, 7, // 0x34 '4' 0x00,0x00,0x00,0x08,0x18,0x28,0x48,0x88,0xFC,0x08,0x08,0x00,0x00, 7, // 0x35 '5' 0x00,0x00,0x00,0x7C,0x40,0x40,0x78,0x04,0x04,0x44,0x38,0x00,0x00, 7, // 0x36 '6' 0x00,0x00,0x00,0x18,0x20,0x40,0x78,0x44,0x44,0x44,0x38,0x00,0x00, 7, // 0x37 '7' 0x00,0x00,0x00,0x7C,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x00,0x00, 7, // 0x38 '8' 0x00,0x00,0x00,0x38,0x44,0x44,0x38,0x44,0x44,0x44,0x38,0x00,0x00, 7, // 0x39 '9' 0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x3C,0x04,0x08,0x30,0x00,0x00, 5, // 0x3A ':' 0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x20,0x20,0x00,0x00, 5, // 0x3B ';' 0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x20,0x20,0x20,0x40, 9, // 0x3C '<' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x18,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x3D '=' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x3E '>' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x0C,0x00,0x03,0x00,0x0C,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x3F '?' 0x00,0x00,0x00,0x70,0x08,0x08,0x10,0x20,0x20,0x00,0x20,0x00,0x00, 10, // 0x40 '@' 0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x20,0x80,0x4E,0x80,0x52,0x80,0x52,0x80,0x52,0x80,0x4D,0x00,0x20,0x00,0x1E,0x00,0x00,0x00, 8, // 0x41 'A' 0x00,0x00,0x00,0x18,0x18,0x24,0x24,0x24,0x7E,0x42,0x42,0x00,0x00, 8, // 0x42 'B' 0x00,0x00,0x00,0x78,0x44,0x44,0x7C,0x42,0x42,0x42,0x7C,0x00,0x00, 9, // 0x43 'C' 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00, 9, // 0x44 'D' 0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x42,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x42,0x00,0x7C,0x00,0x00,0x00,0x00,0x00, 7, // 0x45 'E' 0x00,0x00,0x00,0x7C,0x40,0x40,0x7C,0x40,0x40,0x40,0x7C,0x00,0x00, 6, // 0x46 'F' 0x00,0x00,0x00,0x7C,0x40,0x40,0x78,0x40,0x40,0x40,0x40,0x00,0x00, 9, // 0x47 'G' 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x00,0x40,0x00,0x47,0x00,0x41,0x00,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00, 8, // 0x48 'H' 0x00,0x00,0x00,0x42,0x42,0x42,0x7E,0x42,0x42,0x42,0x42,0x00,0x00, 5, // 0x49 'I' 0x00,0x00,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, 5, // 0x4A 'J' 0x00,0x00,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0xE0,0x00,0x00, 8, // 0x4B 'K' 0x00,0x00,0x00,0x42,0x44,0x48,0x50,0x70,0x48,0x44,0x42,0x00,0x00, 6, // 0x4C 'L' 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7C,0x00,0x00, 9, // 0x4D 'M' 0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x55,0x00,0x55,0x00,0x49,0x00,0x49,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00, 8, // 0x4E 'N' 0x00,0x00,0x00,0x62,0x62,0x52,0x52,0x4A,0x4A,0x46,0x46,0x00,0x00, 9, // 0x4F 'O' 0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x22,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00, 7, // 0x50 'P' 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x78,0x40,0x40,0x40,0x00,0x00, 9, // 0x51 'Q' 0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x22,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x1C,0x00,0x04,0x00,0x03,0x00, 8, // 0x52 'R' 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x78,0x48,0x44,0x42,0x00,0x00, 8, // 0x53 'S' 0x00,0x00,0x00,0x3C,0x42,0x40,0x30,0x0C,0x02,0x42,0x3C,0x00,0x00, 7, // 0x54 'T' 0x00,0x00,0x00,0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, 8, // 0x55 'U' 0x00,0x00,0x00,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00, 8, // 0x56 'V' 0x00,0x00,0x00,0x42,0x42,0x42,0x24,0x24,0x24,0x18,0x18,0x00,0x00, 11, // 0x57 'W' 0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x40,0x44,0x40,0x2A,0x80,0x2A,0x80,0x2A,0x80,0x2A,0x80,0x11,0x00,0x11,0x00,0x00,0x00,0x00,0x00, 8, // 0x58 'X' 0x00,0x00,0x00,0x42,0x42,0x24,0x18,0x18,0x24,0x42,0x42,0x00,0x00, 7, // 0x59 'Y' 0x00,0x00,0x00,0x82,0x44,0x28,0x10,0x10,0x10,0x10,0x10,0x00,0x00, 8, // 0x5A 'Z' 0x00,0x00,0x00,0x7E,0x02,0x04,0x08,0x10,0x20,0x40,0x7E,0x00,0x00, 5, // 0x5B '[' 0x00,0x00,0x70,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x70, 5, // 0x5C '\' 0x00,0x00,0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x00, 5, // 0x5D ']' 0x00,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x70, 9, // 0x5E '^' 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x14,0x00,0x22,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x5F '_' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE, 7, // 0x60 '`' 0x00,0x00,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x61 'a' 0x00,0x00,0x00,0x00,0x00,0x38,0x04,0x3C,0x44,0x44,0x3C,0x00,0x00, 7, // 0x62 'b' 0x00,0x00,0x40,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x78,0x00,0x00, 6, // 0x63 'c' 0x00,0x00,0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x44,0x38,0x00,0x00, 7, // 0x64 'd' 0x00,0x00,0x04,0x04,0x04,0x3C,0x44,0x44,0x44,0x44,0x3C,0x00,0x00, 7, // 0x65 'e' 0x00,0x00,0x00,0x00,0x00,0x38,0x44,0x7C,0x40,0x44,0x38,0x00,0x00, 4, // 0x66 'f' 0x00,0x00,0x30,0x40,0x40,0xF0,0x40,0x40,0x40,0x40,0x40,0x00,0x00, 7, // 0x67 'g' 0x00,0x00,0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x3C,0x04,0x38, 7, // 0x68 'h' 0x00,0x00,0x40,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x00,0x00, 3, // 0x69 'i' 0x00,0x00,0x40,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00, 4, // 0x6A 'j' 0x00,0x00,0x20,0x00,0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0xC0, 7, // 0x6B 'k' 0x00,0x00,0x40,0x40,0x40,0x44,0x48,0x50,0x70,0x48,0x44,0x00,0x00, 3, // 0x6C 'l' 0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00, 11, // 0x6D 'm' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7B,0x80,0x44,0x40,0x44,0x40,0x44,0x40,0x44,0x40,0x44,0x40,0x00,0x00,0x00,0x00, 7, // 0x6E 'n' 0x00,0x00,0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x44,0x00,0x00, 7, // 0x6F 'o' 0x00,0x00,0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x38,0x00,0x00, 7, // 0x70 'p' 0x00,0x00,0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x40,0x40, 7, // 0x71 'q' 0x00,0x00,0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x3C,0x04,0x04, 5, // 0x72 'r' 0x00,0x00,0x00,0x00,0x00,0x58,0x60,0x40,0x40,0x40,0x40,0x00,0x00, 6, // 0x73 's' 0x00,0x00,0x00,0x00,0x00,0x38,0x40,0x60,0x18,0x08,0x70,0x00,0x00, 4, // 0x74 't' 0x00,0x00,0x00,0x40,0x40,0xF0,0x40,0x40,0x40,0x40,0x30,0x00,0x00, 7, // 0x75 'u' 0x00,0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x3C,0x00,0x00, 7, // 0x76 'v' 0x00,0x00,0x00,0x00,0x00,0x44,0x44,0x28,0x28,0x10,0x10,0x00,0x00, 9, // 0x77 'w' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x49,0x00,0x49,0x00,0x55,0x00,0x55,0x00,0x22,0x00,0x22,0x00,0x00,0x00,0x00,0x00, 7, // 0x78 'x' 0x00,0x00,0x00,0x00,0x00,0x44,0x28,0x10,0x10,0x28,0x44,0x00,0x00, 7, // 0x79 'y' 0x00,0x00,0x00,0x00,0x00,0x44,0x28,0x28,0x28,0x10,0x10,0x10,0x20, 6, // 0x7A 'z' 0x00,0x00,0x00,0x00,0x00,0x78,0x08,0x10,0x20,0x40,0x78,0x00,0x00, 7, // 0x7B '{' 0x00,0x00,0x0C,0x10,0x10,0x10,0x10,0x60,0x10,0x10,0x10,0x10,0x0C, 5, // 0x7C '|' 0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, 7, // 0x7D '}' 0x00,0x00,0x60,0x10,0x10,0x10,0x10,0x0C,0x10,0x10,0x10,0x10,0x60, 9, // 0x7E '~' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x31,0x00,0x49,0x00,0x46,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x7F '' 0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x7F,0x80,0x00,0x00,0x00,0x00, 0 }; const int8u verdana13_bold[] = { 13, 3, 32, 128-32, 0x00,0x00,0x0E,0x00,0x1C,0x00,0x2A,0x00,0x45,0x00,0x53,0x00,0x6E,0x00,0x89,0x00,0x97,0x00, 0xA5,0x00,0xB3,0x00,0xC1,0x00,0xDC,0x00,0xEA,0x00,0xF8,0x00,0x06,0x01,0x14,0x01,0x22,0x01, 0x30,0x01,0x3E,0x01,0x4C,0x01,0x5A,0x01,0x68,0x01,0x76,0x01,0x84,0x01,0x92,0x01,0xA0,0x01, 0xAE,0x01,0xBC,0x01,0xD7,0x01,0xF2,0x01,0x0D,0x02,0x1B,0x02,0x36,0x02,0x51,0x02,0x5F,0x02, 0x6D,0x02,0x88,0x02,0x96,0x02,0xA4,0x02,0xBF,0x02,0xDA,0x02,0xE8,0x02,0xF6,0x02,0x04,0x03, 0x12,0x03,0x2D,0x03,0x48,0x03,0x63,0x03,0x71,0x03,0x8C,0x03,0x9A,0x03,0xA8,0x03,0xB6,0x03, 0xD1,0x03,0xDF,0x03,0xFA,0x03,0x08,0x04,0x16,0x04,0x24,0x04,0x32,0x04,0x40,0x04,0x4E,0x04, 0x69,0x04,0x77,0x04,0x85,0x04,0x93,0x04,0xA1,0x04,0xAF,0x04,0xBD,0x04,0xCB,0x04,0xD9,0x04, 0xE7,0x04,0xF5,0x04,0x03,0x05,0x11,0x05,0x1F,0x05,0x2D,0x05,0x48,0x05,0x56,0x05,0x64,0x05, 0x72,0x05,0x80,0x05,0x8E,0x05,0x9C,0x05,0xAA,0x05,0xB8,0x05,0xC6,0x05,0xE1,0x05,0xEF,0x05, 0xFD,0x05,0x0B,0x06,0x19,0x06,0x27,0x06,0x35,0x06,0x50,0x06, 4, // 0x20 ' ' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 4, // 0x21 '!' 0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x60,0x00,0x00, 7, // 0x22 '"' 0x00,0x00,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x23 '#' 0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x00,0x0A,0x00,0x3F,0x00,0x14,0x00,0x14,0x00,0x7E,0x00,0x28,0x00,0x28,0x00,0x00,0x00,0x00,0x00, 8, // 0x24 '$' 0x00,0x00,0x08,0x08,0x3C,0x6A,0x68,0x3C,0x16,0x56,0x3C,0x10,0x10, 14, // 0x25 '%' 0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x80,0x6C,0x80,0x6D,0x00,0x6D,0x70,0x3A,0xD8,0x02,0xD8,0x04,0xD8,0x04,0x70,0x00,0x00,0x00,0x00, 10, // 0x26 '&' 0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x6C,0x00,0x6C,0x00,0x39,0x80,0x6D,0x00,0x66,0x00,0x63,0x00,0x3D,0x80,0x00,0x00,0x00,0x00, 4, // 0x27 ''' 0x00,0x00,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x28 '(' 0x00,0x00,0x18,0x30,0x30,0x60,0x60,0x60,0x60,0x60,0x30,0x30,0x18, 6, // 0x29 ')' 0x00,0x00,0x60,0x30,0x30,0x18,0x18,0x18,0x18,0x18,0x30,0x30,0x60, 8, // 0x2A '*' 0x00,0x00,0x10,0x54,0x38,0x54,0x10,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x2B '+' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x7F,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00, 4, // 0x2C ',' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x60,0x40, 6, // 0x2D '-' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00, 4, // 0x2E '.' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00, 8, // 0x2F '/' 0x00,0x00,0x06,0x06,0x0C,0x0C,0x18,0x18,0x18,0x30,0x30,0x60,0x60, 8, // 0x30 '0' 0x00,0x00,0x00,0x3C,0x66,0x66,0x66,0x66,0x66,0x66,0x3C,0x00,0x00, 8, // 0x31 '1' 0x00,0x00,0x00,0x18,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00, 8, // 0x32 '2' 0x00,0x00,0x00,0x3C,0x66,0x06,0x0C,0x18,0x30,0x60,0x7E,0x00,0x00, 8, // 0x33 '3' 0x00,0x00,0x00,0x3C,0x66,0x06,0x1C,0x06,0x06,0x66,0x3C,0x00,0x00, 8, // 0x34 '4' 0x00,0x00,0x00,0x04,0x0C,0x1C,0x2C,0x4C,0x7E,0x0C,0x0C,0x00,0x00, 8, // 0x35 '5' 0x00,0x00,0x00,0x3E,0x30,0x30,0x3C,0x06,0x06,0x66,0x3C,0x00,0x00, 8, // 0x36 '6' 0x00,0x00,0x00,0x1C,0x30,0x60,0x7C,0x66,0x66,0x66,0x3C,0x00,0x00, 8, // 0x37 '7' 0x00,0x00,0x00,0x7E,0x06,0x0C,0x0C,0x18,0x18,0x30,0x30,0x00,0x00, 8, // 0x38 '8' 0x00,0x00,0x00,0x3C,0x66,0x66,0x3C,0x66,0x66,0x66,0x3C,0x00,0x00, 8, // 0x39 '9' 0x00,0x00,0x00,0x3C,0x66,0x66,0x66,0x3E,0x06,0x0C,0x38,0x00,0x00, 4, // 0x3A ':' 0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x60,0x60,0x00,0x00, 4, // 0x3B ';' 0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x60,0x60,0x60,0x40, 9, // 0x3C '<' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x0C,0x00,0x30,0x00,0x40,0x00,0x30,0x00,0x0C,0x00,0x03,0x00,0x00,0x00,0x00,0x00, 9, // 0x3D '=' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x3E '>' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x01,0x00,0x06,0x00,0x18,0x00,0x60,0x00,0x00,0x00,0x00,0x00, 7, // 0x3F '?' 0x00,0x00,0x00,0x38,0x4C,0x0C,0x18,0x30,0x30,0x00,0x30,0x00,0x00, 11, // 0x40 '@' 0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x80,0x20,0x40,0x4F,0x40,0x5B,0x40,0x5B,0x40,0x5B,0x40,0x4F,0x80,0x20,0x00,0x1F,0x00,0x00,0x00, 9, // 0x41 'A' 0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x1C,0x00,0x36,0x00,0x36,0x00,0x36,0x00,0x7F,0x00,0x63,0x00,0x63,0x00,0x00,0x00,0x00,0x00, 8, // 0x42 'B' 0x00,0x00,0x00,0x7C,0x66,0x66,0x7C,0x66,0x66,0x66,0x7C,0x00,0x00, 8, // 0x43 'C' 0x00,0x00,0x00,0x3C,0x62,0x60,0x60,0x60,0x60,0x62,0x3C,0x00,0x00, 9, // 0x44 'D' 0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x66,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x66,0x00,0x7C,0x00,0x00,0x00,0x00,0x00, 8, // 0x45 'E' 0x00,0x00,0x00,0x7E,0x60,0x60,0x7E,0x60,0x60,0x60,0x7E,0x00,0x00, 8, // 0x46 'F' 0x00,0x00,0x00,0x7E,0x60,0x60,0x7E,0x60,0x60,0x60,0x60,0x00,0x00, 9, // 0x47 'G' 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x61,0x00,0x60,0x00,0x60,0x00,0x67,0x00,0x63,0x00,0x63,0x00,0x3F,0x00,0x00,0x00,0x00,0x00, 9, // 0x48 'H' 0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x7F,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x00,0x00,0x00,0x00, 6, // 0x49 'I' 0x00,0x00,0x00,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00, 6, // 0x4A 'J' 0x00,0x00,0x00,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0xF0,0x00,0x00, 8, // 0x4B 'K' 0x00,0x00,0x00,0x66,0x6C,0x78,0x70,0x70,0x78,0x6C,0x66,0x00,0x00, 7, // 0x4C 'L' 0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x7E,0x00,0x00, 10, // 0x4D 'M' 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x80,0x71,0x80,0x7B,0x80,0x5D,0x80,0x49,0x80,0x41,0x80,0x41,0x80,0x41,0x80,0x00,0x00,0x00,0x00, 9, // 0x4E 'N' 0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x61,0x00,0x71,0x00,0x59,0x00,0x4D,0x00,0x47,0x00,0x43,0x00,0x41,0x00,0x00,0x00,0x00,0x00, 9, // 0x4F 'O' 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00, 8, // 0x50 'P' 0x00,0x00,0x00,0x7C,0x66,0x66,0x66,0x7C,0x60,0x60,0x60,0x00,0x00, 9, // 0x51 'Q' 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x0C,0x00,0x07,0x00, 8, // 0x52 'R' 0x00,0x00,0x00,0x7C,0x66,0x66,0x66,0x7C,0x6C,0x66,0x63,0x00,0x00, 8, // 0x53 'S' 0x00,0x00,0x00,0x3C,0x62,0x60,0x7C,0x3E,0x06,0x46,0x3C,0x00,0x00, 8, // 0x54 'T' 0x00,0x00,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00, 9, // 0x55 'U' 0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00, 8, // 0x56 'V' 0x00,0x00,0x00,0x66,0x66,0x66,0x3C,0x3C,0x3C,0x18,0x18,0x00,0x00, 12, // 0x57 'W' 0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x60,0x66,0x60,0x66,0x60,0x36,0xC0,0x3F,0xC0,0x39,0xC0,0x19,0x80,0x19,0x80,0x00,0x00,0x00,0x00, 8, // 0x58 'X' 0x00,0x00,0x00,0x66,0x66,0x3C,0x18,0x18,0x3C,0x66,0x66,0x00,0x00, 8, // 0x59 'Y' 0x00,0x00,0x00,0x66,0x66,0x3C,0x3C,0x18,0x18,0x18,0x18,0x00,0x00, 8, // 0x5A 'Z' 0x00,0x00,0x00,0x7E,0x06,0x0E,0x1C,0x38,0x70,0x60,0x7E,0x00,0x00, 6, // 0x5B '[' 0x00,0x00,0x78,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x78, 8, // 0x5C '\' 0x00,0x00,0x60,0x60,0x30,0x30,0x18,0x18,0x18,0x0C,0x0C,0x06,0x06, 6, // 0x5D ']' 0x00,0x00,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x78, 10, // 0x5E '^' 0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x5F '_' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF, 8, // 0x60 '`' 0x00,0x00,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x61 'a' 0x00,0x00,0x00,0x00,0x00,0x3C,0x06,0x3E,0x66,0x66,0x3E,0x00,0x00, 8, // 0x62 'b' 0x00,0x00,0x60,0x60,0x60,0x7C,0x66,0x66,0x66,0x66,0x7C,0x00,0x00, 7, // 0x63 'c' 0x00,0x00,0x00,0x00,0x00,0x3C,0x60,0x60,0x60,0x60,0x3C,0x00,0x00, 8, // 0x64 'd' 0x00,0x00,0x06,0x06,0x06,0x3E,0x66,0x66,0x66,0x66,0x3E,0x00,0x00, 8, // 0x65 'e' 0x00,0x00,0x00,0x00,0x00,0x3C,0x66,0x7E,0x60,0x62,0x3C,0x00,0x00, 5, // 0x66 'f' 0x00,0x00,0x38,0x60,0x60,0xF8,0x60,0x60,0x60,0x60,0x60,0x00,0x00, 8, // 0x67 'g' 0x00,0x00,0x00,0x00,0x00,0x3E,0x66,0x66,0x66,0x66,0x3E,0x06,0x3C, 8, // 0x68 'h' 0x00,0x00,0x60,0x60,0x60,0x7C,0x66,0x66,0x66,0x66,0x66,0x00,0x00, 4, // 0x69 'i' 0x00,0x00,0x00,0x60,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00, 5, // 0x6A 'j' 0x00,0x00,0x00,0x30,0x00,0x70,0x30,0x30,0x30,0x30,0x30,0x30,0xE0, 8, // 0x6B 'k' 0x00,0x00,0x60,0x60,0x60,0x66,0x6C,0x78,0x78,0x6C,0x66,0x00,0x00, 4, // 0x6C 'l' 0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00, 12, // 0x6D 'm' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7D,0xC0,0x66,0x60,0x66,0x60,0x66,0x60,0x66,0x60,0x66,0x60,0x00,0x00,0x00,0x00, 8, // 0x6E 'n' 0x00,0x00,0x00,0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x66,0x00,0x00, 8, // 0x6F 'o' 0x00,0x00,0x00,0x00,0x00,0x3C,0x66,0x66,0x66,0x66,0x3C,0x00,0x00, 8, // 0x70 'p' 0x00,0x00,0x00,0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x7C,0x60,0x60, 8, // 0x71 'q' 0x00,0x00,0x00,0x00,0x00,0x3E,0x66,0x66,0x66,0x66,0x3E,0x06,0x06, 6, // 0x72 'r' 0x00,0x00,0x00,0x00,0x00,0x6C,0x7C,0x60,0x60,0x60,0x60,0x00,0x00, 7, // 0x73 's' 0x00,0x00,0x00,0x00,0x00,0x3C,0x60,0x78,0x3C,0x0C,0x78,0x00,0x00, 5, // 0x74 't' 0x00,0x00,0x00,0x60,0x60,0xF8,0x60,0x60,0x60,0x60,0x38,0x00,0x00, 8, // 0x75 'u' 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x3E,0x00,0x00, 8, // 0x76 'v' 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x3C,0x3C,0x18,0x00,0x00, 10, // 0x77 'w' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6D,0x80,0x6D,0x80,0x6D,0x80,0x6D,0x80,0x33,0x00,0x33,0x00,0x00,0x00,0x00,0x00, 8, // 0x78 'x' 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x3C,0x3C,0x66,0x66,0x00,0x00, 8, // 0x79 'y' 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x3C,0x3C,0x18,0x18,0x30,0x30, 7, // 0x7A 'z' 0x00,0x00,0x00,0x00,0x00,0x7C,0x0C,0x18,0x30,0x60,0x7C,0x00,0x00, 8, // 0x7B '{' 0x00,0x00,0x0E,0x18,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0E, 6, // 0x7C '|' 0x00,0x00,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30, 8, // 0x7D '}' 0x00,0x00,0x70,0x18,0x18,0x18,0x18,0x0E,0x18,0x18,0x18,0x18,0x70, 9, // 0x7E '~' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x31,0x00,0x49,0x00,0x49,0x00,0x46,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x7F '' 0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x7F,0x80,0x00,0x00,0x00,0x00, 0 }; const int8u verdana14[] = { 14, 3, 32, 128-32, 0x00,0x00,0x0F,0x00,0x1E,0x00,0x2D,0x00,0x4A,0x00,0x59,0x00,0x76,0x00,0x93,0x00,0xA2,0x00, 0xB1,0x00,0xC0,0x00,0xCF,0x00,0xEC,0x00,0xFB,0x00,0x0A,0x01,0x19,0x01,0x28,0x01,0x37,0x01, 0x46,0x01,0x55,0x01,0x64,0x01,0x73,0x01,0x82,0x01,0x91,0x01,0xA0,0x01,0xAF,0x01,0xBE,0x01, 0xCD,0x01,0xDC,0x01,0xF9,0x01,0x16,0x02,0x33,0x02,0x42,0x02,0x5F,0x02,0x6E,0x02,0x7D,0x02, 0x9A,0x02,0xB7,0x02,0xC6,0x02,0xD5,0x02,0xF2,0x02,0x0F,0x03,0x1E,0x03,0x2D,0x03,0x3C,0x03, 0x4B,0x03,0x68,0x03,0x85,0x03,0xA2,0x03,0xB1,0x03,0xCE,0x03,0xDD,0x03,0xEC,0x03,0xFB,0x03, 0x18,0x04,0x27,0x04,0x44,0x04,0x53,0x04,0x62,0x04,0x71,0x04,0x80,0x04,0x8F,0x04,0x9E,0x04, 0xBB,0x04,0xCA,0x04,0xD9,0x04,0xE8,0x04,0xF7,0x04,0x06,0x05,0x15,0x05,0x24,0x05,0x33,0x05, 0x42,0x05,0x51,0x05,0x60,0x05,0x6F,0x05,0x7E,0x05,0x8D,0x05,0xAA,0x05,0xB9,0x05,0xC8,0x05, 0xD7,0x05,0xE6,0x05,0xF5,0x05,0x04,0x06,0x13,0x06,0x22,0x06,0x31,0x06,0x4E,0x06,0x5D,0x06, 0x6C,0x06,0x7B,0x06,0x8A,0x06,0x99,0x06,0xA8,0x06,0xC5,0x06, 4, // 0x20 ' ' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x21 '!' 0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00, 6, // 0x22 '"' 0x00,0x00,0x48,0x48,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x23 '#' 0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x00,0x09,0x00,0x12,0x00,0x3F,0x80,0x12,0x00,0x12,0x00,0x7F,0x00,0x24,0x00,0x24,0x00,0x00,0x00,0x00,0x00, 8, // 0x24 '$' 0x00,0x00,0x10,0x10,0x3E,0x50,0x50,0x30,0x1C,0x12,0x12,0x7C,0x10,0x10, 13, // 0x25 '%' 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x80,0x49,0x00,0x49,0x00,0x4A,0x00,0x32,0x60,0x02,0x90,0x04,0x90,0x04,0x90,0x08,0x60,0x00,0x00,0x00,0x00, 10, // 0x26 '&' 0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x44,0x00,0x44,0x00,0x44,0x00,0x39,0x00,0x45,0x00,0x42,0x00,0x43,0x00,0x3C,0x80,0x00,0x00,0x00,0x00, 3, // 0x27 ''' 0x00,0x00,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x28 '(' 0x00,0x00,0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x10, 5, // 0x29 ')' 0x00,0x00,0x40,0x20,0x20,0x10,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x40, 8, // 0x2A '*' 0x00,0x00,0x10,0x54,0x38,0x54,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x2B '+' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x7F,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00, 4, // 0x2C ',' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x40, 5, // 0x2D '-' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00, 4, // 0x2E '.' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00, 5, // 0x2F '/' 0x00,0x00,0x08,0x08,0x10,0x10,0x10,0x20,0x20,0x20,0x40,0x40,0x40,0x80, 8, // 0x30 '0' 0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00, 8, // 0x31 '1' 0x00,0x00,0x00,0x08,0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x3E,0x00,0x00, 8, // 0x32 '2' 0x00,0x00,0x00,0x3C,0x42,0x42,0x02,0x04,0x18,0x20,0x40,0x7E,0x00,0x00, 8, // 0x33 '3' 0x00,0x00,0x00,0x3C,0x42,0x02,0x02,0x1C,0x02,0x02,0x42,0x3C,0x00,0x00, 8, // 0x34 '4' 0x00,0x00,0x00,0x04,0x0C,0x14,0x24,0x44,0x7F,0x04,0x04,0x04,0x00,0x00, 8, // 0x35 '5' 0x00,0x00,0x00,0x7E,0x40,0x40,0x7C,0x02,0x02,0x02,0x42,0x3C,0x00,0x00, 8, // 0x36 '6' 0x00,0x00,0x00,0x1C,0x20,0x40,0x7C,0x42,0x42,0x42,0x42,0x3C,0x00,0x00, 8, // 0x37 '7' 0x00,0x00,0x00,0x7E,0x02,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x00,0x00, 8, // 0x38 '8' 0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x3C,0x42,0x42,0x42,0x3C,0x00,0x00, 8, // 0x39 '9' 0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x42,0x3E,0x02,0x04,0x38,0x00,0x00, 5, // 0x3A ':' 0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00,0x20,0x20,0x00,0x00, 5, // 0x3B ';' 0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00,0x20,0x20,0x20,0x40, 9, // 0x3C '<' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x0C,0x00,0x30,0x00,0x40,0x00,0x30,0x00,0x0C,0x00,0x03,0x00,0x00,0x00,0x00,0x00, 9, // 0x3D '=' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x3E '>' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x01,0x00,0x06,0x00,0x18,0x00,0x60,0x00,0x00,0x00,0x00,0x00, 7, // 0x3F '?' 0x00,0x00,0x00,0x38,0x44,0x04,0x04,0x08,0x10,0x10,0x00,0x10,0x00,0x00, 12, // 0x40 '@' 0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x30,0xC0,0x27,0x40,0x49,0x20,0x49,0x20,0x49,0x20,0x49,0x20,0x27,0xC0,0x30,0x00,0x0F,0x00,0x00,0x00, 8, // 0x41 'A' 0x00,0x00,0x00,0x18,0x18,0x24,0x24,0x42,0x42,0x7E,0x81,0x81,0x00,0x00, 8, // 0x42 'B' 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x7C,0x42,0x42,0x42,0x7C,0x00,0x00, 9, // 0x43 'C' 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00, 9, // 0x44 'D' 0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x42,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x42,0x00,0x7C,0x00,0x00,0x00,0x00,0x00, 8, // 0x45 'E' 0x00,0x00,0x00,0x7E,0x40,0x40,0x40,0x7E,0x40,0x40,0x40,0x7E,0x00,0x00, 7, // 0x46 'F' 0x00,0x00,0x00,0x7E,0x40,0x40,0x40,0x7C,0x40,0x40,0x40,0x40,0x00,0x00, 9, // 0x47 'G' 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x00,0x40,0x00,0x47,0x00,0x41,0x00,0x41,0x00,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00, 9, // 0x48 'H' 0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x7F,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00, 5, // 0x49 'I' 0x00,0x00,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, 5, // 0x4A 'J' 0x00,0x00,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xE0,0x00,0x00, 8, // 0x4B 'K' 0x00,0x00,0x00,0x42,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x42,0x00,0x00, 7, // 0x4C 'L' 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7E,0x00,0x00, 10, // 0x4D 'M' 0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x52,0x80,0x52,0x80,0x52,0x80,0x4C,0x80,0x4C,0x80,0x40,0x80,0x40,0x80,0x00,0x00,0x00,0x00, 9, // 0x4E 'N' 0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x00,0x61,0x00,0x51,0x00,0x51,0x00,0x49,0x00,0x45,0x00,0x45,0x00,0x43,0x00,0x43,0x00,0x00,0x00,0x00,0x00, 10, // 0x4F 'O' 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00, 8, // 0x50 'P' 0x00,0x00,0x00,0x7C,0x42,0x42,0x42,0x42,0x7C,0x40,0x40,0x40,0x00,0x00, 10, // 0x51 'Q' 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x02,0x00,0x01,0x80, 8, // 0x52 'R' 0x00,0x00,0x00,0x7C,0x42,0x42,0x42,0x7C,0x48,0x44,0x42,0x41,0x00,0x00, 8, // 0x53 'S' 0x00,0x00,0x00,0x3C,0x42,0x40,0x40,0x3C,0x02,0x02,0x42,0x3C,0x00,0x00, 7, // 0x54 'T' 0x00,0x00,0x00,0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, 9, // 0x55 'U' 0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00, 8, // 0x56 'V' 0x00,0x00,0x00,0x81,0x81,0x42,0x42,0x42,0x24,0x24,0x18,0x18,0x00,0x00, 13, // 0x57 'W' 0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x10,0x42,0x10,0x45,0x10,0x45,0x10,0x25,0x20,0x28,0xA0,0x28,0xA0,0x10,0x40,0x10,0x40,0x00,0x00,0x00,0x00, 8, // 0x58 'X' 0x00,0x00,0x00,0x42,0x42,0x24,0x18,0x18,0x18,0x24,0x42,0x42,0x00,0x00, 7, // 0x59 'Y' 0x00,0x00,0x00,0x82,0x44,0x44,0x28,0x10,0x10,0x10,0x10,0x10,0x00,0x00, 8, // 0x5A 'Z' 0x00,0x00,0x00,0x7E,0x02,0x04,0x08,0x10,0x10,0x20,0x40,0x7E,0x00,0x00, 5, // 0x5B '[' 0x00,0x00,0x70,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x70, 5, // 0x5C '\' 0x00,0x00,0x80,0x80,0x40,0x40,0x40,0x20,0x20,0x10,0x10,0x10,0x08,0x08, 5, // 0x5D ']' 0x00,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x70, 10, // 0x5E '^' 0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x12,0x00,0x21,0x00,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x5F '_' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF, 8, // 0x60 '`' 0x00,0x00,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x61 'a' 0x00,0x00,0x00,0x00,0x00,0x3C,0x02,0x02,0x3E,0x42,0x42,0x3E,0x00,0x00, 8, // 0x62 'b' 0x00,0x00,0x40,0x40,0x40,0x5C,0x62,0x42,0x42,0x42,0x42,0x7C,0x00,0x00, 6, // 0x63 'c' 0x00,0x00,0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x40,0x44,0x38,0x00,0x00, 8, // 0x64 'd' 0x00,0x00,0x02,0x02,0x02,0x3E,0x42,0x42,0x42,0x42,0x46,0x3A,0x00,0x00, 8, // 0x65 'e' 0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x7E,0x40,0x42,0x3C,0x00,0x00, 4, // 0x66 'f' 0x00,0x00,0x30,0x40,0x40,0xF0,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00, 8, // 0x67 'g' 0x00,0x00,0x00,0x00,0x00,0x3E,0x42,0x42,0x42,0x42,0x46,0x3A,0x02,0x3C, 8, // 0x68 'h' 0x00,0x00,0x40,0x40,0x40,0x5C,0x62,0x42,0x42,0x42,0x42,0x42,0x00,0x00, 3, // 0x69 'i' 0x00,0x00,0x40,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00, 4, // 0x6A 'j' 0x00,0x00,0x20,0x00,0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xC0, 7, // 0x6B 'k' 0x00,0x00,0x40,0x40,0x40,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x00,0x00, 3, // 0x6C 'l' 0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00, 11, // 0x6D 'm' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7B,0x80,0x44,0x40,0x44,0x40,0x44,0x40,0x44,0x40,0x44,0x40,0x44,0x40,0x00,0x00,0x00,0x00, 8, // 0x6E 'n' 0x00,0x00,0x00,0x00,0x00,0x5C,0x62,0x42,0x42,0x42,0x42,0x42,0x00,0x00, 8, // 0x6F 'o' 0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00, 8, // 0x70 'p' 0x00,0x00,0x00,0x00,0x00,0x5C,0x62,0x42,0x42,0x42,0x42,0x7C,0x40,0x40, 8, // 0x71 'q' 0x00,0x00,0x00,0x00,0x00,0x3E,0x42,0x42,0x42,0x42,0x46,0x3A,0x02,0x02, 5, // 0x72 'r' 0x00,0x00,0x00,0x00,0x00,0x58,0x60,0x40,0x40,0x40,0x40,0x40,0x00,0x00, 7, // 0x73 's' 0x00,0x00,0x00,0x00,0x00,0x3C,0x40,0x40,0x38,0x04,0x04,0x78,0x00,0x00, 5, // 0x74 't' 0x00,0x00,0x00,0x40,0x40,0xF8,0x40,0x40,0x40,0x40,0x40,0x38,0x00,0x00, 8, // 0x75 'u' 0x00,0x00,0x00,0x00,0x00,0x42,0x42,0x42,0x42,0x42,0x46,0x3A,0x00,0x00, 7, // 0x76 'v' 0x00,0x00,0x00,0x00,0x00,0x44,0x44,0x28,0x28,0x28,0x10,0x10,0x00,0x00, 11, // 0x77 'w' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x40,0x44,0x40,0x2A,0x80,0x2A,0x80,0x2A,0x80,0x11,0x00,0x11,0x00,0x00,0x00,0x00,0x00, 7, // 0x78 'x' 0x00,0x00,0x00,0x00,0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x00,0x00, 7, // 0x79 'y' 0x00,0x00,0x00,0x00,0x00,0x44,0x44,0x28,0x28,0x28,0x10,0x10,0x10,0x20, 7, // 0x7A 'z' 0x00,0x00,0x00,0x00,0x00,0x7C,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,0x00, 8, // 0x7B '{' 0x00,0x00,0x0C,0x10,0x10,0x10,0x10,0x60,0x10,0x10,0x10,0x10,0x10,0x0C, 5, // 0x7C '|' 0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, 8, // 0x7D '}' 0x00,0x00,0x30,0x08,0x08,0x08,0x08,0x06,0x08,0x08,0x08,0x08,0x08,0x30, 10, // 0x7E '~' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x80,0x4C,0x80,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 12, // 0x7F '' 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xE0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3F,0xE0,0x00,0x00,0x00,0x00, 0 }; const int8u verdana14_bold[] = { 14, 3, 32, 128-32, 0x00,0x00,0x0F,0x00,0x1E,0x00,0x2D,0x00,0x4A,0x00,0x67,0x00,0x84,0x00,0xA1,0x00,0xB0,0x00, 0xBF,0x00,0xCE,0x00,0xEB,0x00,0x08,0x01,0x17,0x01,0x26,0x01,0x35,0x01,0x44,0x01,0x61,0x01, 0x7E,0x01,0x9B,0x01,0xB8,0x01,0xD5,0x01,0xF2,0x01,0x0F,0x02,0x2C,0x02,0x49,0x02,0x66,0x02, 0x75,0x02,0x84,0x02,0xA1,0x02,0xBE,0x02,0xDB,0x02,0xEA,0x02,0x07,0x03,0x24,0x03,0x41,0x03, 0x5E,0x03,0x7B,0x03,0x8A,0x03,0x99,0x03,0xB6,0x03,0xD3,0x03,0xE2,0x03,0xF1,0x03,0x0E,0x04, 0x1D,0x04,0x3A,0x04,0x57,0x04,0x74,0x04,0x91,0x04,0xAE,0x04,0xCB,0x04,0xE8,0x04,0xF7,0x04, 0x14,0x05,0x31,0x05,0x4E,0x05,0x6B,0x05,0x88,0x05,0x97,0x05,0xA6,0x05,0xB5,0x05,0xC4,0x05, 0xE1,0x05,0xFE,0x05,0x1B,0x06,0x2A,0x06,0x39,0x06,0x48,0x06,0x57,0x06,0x66,0x06,0x75,0x06, 0x84,0x06,0x93,0x06,0xA2,0x06,0xB1,0x06,0xC0,0x06,0xCF,0x06,0xEC,0x06,0xFB,0x06,0x0A,0x07, 0x19,0x07,0x28,0x07,0x37,0x07,0x46,0x07,0x55,0x07,0x64,0x07,0x73,0x07,0x90,0x07,0x9F,0x07, 0xAE,0x07,0xBD,0x07,0xDA,0x07,0xE9,0x07,0x06,0x08,0x23,0x08, 4, // 0x20 ' ' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x21 '!' 0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x60,0x60,0x00,0x00, 7, // 0x22 '"' 0x00,0x00,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x23 '#' 0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x00,0x09,0x00,0x3F,0x80,0x3F,0x80,0x12,0x00,0x7F,0x00,0x7F,0x00,0x24,0x00,0x24,0x00,0x00,0x00,0x00,0x00, 9, // 0x24 '$' 0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x3E,0x00,0x69,0x00,0x68,0x00,0x7E,0x00,0x3F,0x00,0x0B,0x00,0x4B,0x00,0x3E,0x00,0x08,0x00,0x08,0x00, 15, // 0x25 '%' 0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x40,0x6C,0x40,0x6C,0x80,0x6C,0xB8,0x6D,0x6C,0x3A,0x6C,0x02,0x6C,0x04,0x6C,0x04,0x38,0x00,0x00,0x00,0x00, 10, // 0x26 '&' 0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x39,0x80,0x6D,0x00,0x66,0x00,0x63,0x00,0x3D,0x80,0x00,0x00,0x00,0x00, 4, // 0x27 ''' 0x00,0x00,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x28 '(' 0x00,0x00,0x18,0x30,0x30,0x60,0x60,0x60,0x60,0x60,0x60,0x30,0x30,0x18, 7, // 0x29 ')' 0x00,0x00,0x30,0x18,0x18,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x18,0x18,0x30, 9, // 0x2A '*' 0x00,0x00,0x00,0x00,0x08,0x00,0x2A,0x00,0x1C,0x00,0x1C,0x00,0x2A,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x2B '+' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x7F,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 4, // 0x2C ',' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x60,0x40, 6, // 0x2D '-' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00, 4, // 0x2E '.' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00, 8, // 0x2F '/' 0x00,0x00,0x06,0x06,0x0C,0x0C,0x0C,0x18,0x18,0x30,0x30,0x30,0x60,0x60, 9, // 0x30 '0' 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00, 9, // 0x31 '1' 0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x3C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x3F,0x00,0x00,0x00,0x00,0x00, 9, // 0x32 '2' 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x03,0x00,0x03,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x7F,0x00,0x00,0x00,0x00,0x00, 9, // 0x33 '3' 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x03,0x00,0x03,0x00,0x1E,0x00,0x03,0x00,0x03,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00, 9, // 0x34 '4' 0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x0E,0x00,0x16,0x00,0x16,0x00,0x26,0x00,0x46,0x00,0x7F,0x00,0x06,0x00,0x06,0x00,0x00,0x00,0x00,0x00, 9, // 0x35 '5' 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x30,0x00,0x30,0x00,0x3E,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00, 9, // 0x36 '6' 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x30,0x00,0x60,0x00,0x7E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00, 9, // 0x37 '7' 0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x03,0x00,0x06,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x00,0x00, 9, // 0x38 '8' 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00, 9, // 0x39 '9' 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3F,0x00,0x03,0x00,0x06,0x00,0x3C,0x00,0x00,0x00,0x00,0x00, 5, // 0x3A ':' 0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x60,0x60,0x00,0x00, 5, // 0x3B ';' 0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x60,0x60,0x60,0x40, 10, // 0x3C '<' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x06,0x00,0x18,0x00,0x60,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x01,0x00,0x00,0x00,0x00,0x00, 10, // 0x3D '=' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x3E '>' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x30,0x00,0x0C,0x00,0x03,0x00,0x03,0x00,0x0C,0x00,0x30,0x00,0x40,0x00,0x00,0x00,0x00,0x00, 7, // 0x3F '?' 0x00,0x00,0x00,0x38,0x4C,0x0C,0x18,0x30,0x30,0x00,0x30,0x30,0x00,0x00, 12, // 0x40 '@' 0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x30,0xC0,0x2F,0x40,0x5B,0x20,0x5B,0x20,0x5B,0x20,0x5B,0x20,0x2F,0xC0,0x30,0x00,0x0F,0x00,0x00,0x00, 9, // 0x41 'A' 0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x1C,0x00,0x36,0x00,0x36,0x00,0x36,0x00,0x36,0x00,0x7F,0x00,0x63,0x00,0x63,0x00,0x00,0x00,0x00,0x00, 9, // 0x42 'B' 0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x66,0x00,0x66,0x00,0x66,0x00,0x7E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x7E,0x00,0x00,0x00,0x00,0x00, 9, // 0x43 'C' 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x31,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x31,0x00,0x1E,0x00,0x00,0x00,0x00,0x00, 10, // 0x44 'D' 0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x63,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x00,0x7E,0x00,0x00,0x00,0x00,0x00, 8, // 0x45 'E' 0x00,0x00,0x00,0x7E,0x60,0x60,0x60,0x7E,0x60,0x60,0x60,0x7E,0x00,0x00, 8, // 0x46 'F' 0x00,0x00,0x00,0x7E,0x60,0x60,0x60,0x7E,0x60,0x60,0x60,0x60,0x00,0x00, 10, // 0x47 'G' 0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x30,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x67,0x80,0x61,0x80,0x31,0x80,0x1F,0x80,0x00,0x00,0x00,0x00, 10, // 0x48 'H' 0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x7F,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00, 6, // 0x49 'I' 0x00,0x00,0x00,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00, 7, // 0x4A 'J' 0x00,0x00,0x00,0x7C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0xF8,0x00,0x00, 9, // 0x4B 'K' 0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x66,0x00,0x6C,0x00,0x78,0x00,0x70,0x00,0x78,0x00,0x6C,0x00,0x66,0x00,0x63,0x00,0x00,0x00,0x00,0x00, 8, // 0x4C 'L' 0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x7F,0x00,0x00, 11, // 0x4D 'M' 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xC0,0x71,0xC0,0x71,0xC0,0x5A,0xC0,0x5A,0xC0,0x4C,0xC0,0x4C,0xC0,0x40,0xC0,0x40,0xC0,0x00,0x00,0x00,0x00, 10, // 0x4E 'N' 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x80,0x70,0x80,0x58,0x80,0x58,0x80,0x4C,0x80,0x46,0x80,0x46,0x80,0x43,0x80,0x41,0x80,0x00,0x00,0x00,0x00, 11, // 0x4F 'O' 0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x31,0x80,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x31,0x80,0x1F,0x00,0x00,0x00,0x00,0x00, 9, // 0x50 'P' 0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x7E,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00, 11, // 0x51 'Q' 0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x31,0x80,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x31,0x80,0x1F,0x00,0x06,0x00,0x03,0xC0, 9, // 0x52 'R' 0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x7E,0x00,0x6C,0x00,0x66,0x00,0x63,0x00,0x61,0x80,0x00,0x00,0x00,0x00, 9, // 0x53 'S' 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x61,0x00,0x60,0x00,0x70,0x00,0x3E,0x00,0x07,0x00,0x03,0x00,0x43,0x00,0x3E,0x00,0x00,0x00,0x00,0x00, 8, // 0x54 'T' 0x00,0x00,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00, 10, // 0x55 'U' 0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x3F,0x00,0x00,0x00,0x00,0x00, 9, // 0x56 'V' 0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x36,0x00,0x36,0x00,0x36,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x00,0x00,0x00,0x00, 14, // 0x57 'W' 0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x18,0x63,0x18,0x63,0x18,0x33,0x30,0x37,0xB0,0x34,0xB0,0x1C,0xE0,0x18,0x60,0x18,0x60,0x00,0x00,0x00,0x00, 9, // 0x58 'X' 0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x36,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x36,0x00,0x63,0x00,0x63,0x00,0x00,0x00,0x00,0x00, 10, // 0x59 'Y' 0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00, 8, // 0x5A 'Z' 0x00,0x00,0x00,0x7E,0x0C,0x0C,0x18,0x18,0x30,0x30,0x60,0x7E,0x00,0x00, 6, // 0x5B '[' 0x00,0x00,0x78,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x78, 8, // 0x5C '\' 0x00,0x00,0x60,0x60,0x30,0x30,0x30,0x18,0x18,0x0C,0x0C,0x0C,0x06,0x06, 6, // 0x5D ']' 0x00,0x00,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x78, 10, // 0x5E '^' 0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 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,0xFF,0x80, 9, // 0x60 '`' 0x00,0x00,0x00,0x00,0x30,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x61 'a' 0x00,0x00,0x00,0x00,0x00,0x3C,0x06,0x3E,0x66,0x66,0x66,0x3E,0x00,0x00, 8, // 0x62 'b' 0x00,0x00,0x60,0x60,0x60,0x7C,0x66,0x66,0x66,0x66,0x66,0x7C,0x00,0x00, 7, // 0x63 'c' 0x00,0x00,0x00,0x00,0x00,0x3C,0x62,0x60,0x60,0x60,0x62,0x3C,0x00,0x00, 8, // 0x64 'd' 0x00,0x00,0x06,0x06,0x06,0x3E,0x66,0x66,0x66,0x66,0x66,0x3E,0x00,0x00, 8, // 0x65 'e' 0x00,0x00,0x00,0x00,0x00,0x3C,0x66,0x66,0x7E,0x60,0x62,0x3C,0x00,0x00, 5, // 0x66 'f' 0x00,0x00,0x38,0x60,0x60,0xF8,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00, 8, // 0x67 'g' 0x00,0x00,0x00,0x00,0x00,0x3E,0x66,0x66,0x66,0x66,0x66,0x3E,0x06,0x3C, 8, // 0x68 'h' 0x00,0x00,0x60,0x60,0x60,0x7C,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00, 4, // 0x69 'i' 0x00,0x00,0x60,0x60,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00, 5, // 0x6A 'j' 0x00,0x00,0x30,0x30,0x00,0x70,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0xE0, 8, // 0x6B 'k' 0x00,0x00,0x60,0x60,0x60,0x66,0x6C,0x78,0x78,0x6C,0x66,0x63,0x00,0x00, 4, // 0x6C 'l' 0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00, 12, // 0x6D 'm' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6C,0xC0,0x77,0x60,0x66,0x60,0x66,0x60,0x66,0x60,0x66,0x60,0x66,0x60,0x00,0x00,0x00,0x00, 8, // 0x6E 'n' 0x00,0x00,0x00,0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00, 8, // 0x6F 'o' 0x00,0x00,0x00,0x00,0x00,0x3C,0x66,0x66,0x66,0x66,0x66,0x3C,0x00,0x00, 8, // 0x70 'p' 0x00,0x00,0x00,0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0x60, 8, // 0x71 'q' 0x00,0x00,0x00,0x00,0x00,0x3E,0x66,0x66,0x66,0x66,0x66,0x3E,0x06,0x06, 6, // 0x72 'r' 0x00,0x00,0x00,0x00,0x00,0x6C,0x7C,0x60,0x60,0x60,0x60,0x60,0x00,0x00, 7, // 0x73 's' 0x00,0x00,0x00,0x00,0x00,0x3C,0x60,0x60,0x38,0x0C,0x0C,0x78,0x00,0x00, 5, // 0x74 't' 0x00,0x00,0x00,0x60,0x60,0xF8,0x60,0x60,0x60,0x60,0x60,0x38,0x00,0x00, 8, // 0x75 'u' 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x3E,0x00,0x00, 8, // 0x76 'v' 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x3C,0x3C,0x3C,0x18,0x00,0x00, 12, // 0x77 'w' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x60,0x66,0x60,0x66,0x60,0x69,0x60,0x39,0xC0,0x30,0xC0,0x30,0xC0,0x00,0x00,0x00,0x00, 8, // 0x78 'x' 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x3C,0x18,0x3C,0x66,0x66,0x00,0x00, 8, // 0x79 'y' 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x3C,0x3C,0x3C,0x18,0x18,0x30, 7, // 0x7A 'z' 0x00,0x00,0x00,0x00,0x00,0x7C,0x0C,0x18,0x38,0x30,0x60,0x7C,0x00,0x00, 9, // 0x7B '{' 0x00,0x00,0x00,0x00,0x0E,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x70,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x0E,0x00, 6, // 0x7C '|' 0x00,0x00,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30, 9, // 0x7D '}' 0x00,0x00,0x00,0x00,0x38,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x07,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x38,0x00, 10, // 0x7E '~' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x80,0x48,0x80,0x44,0x80,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 12, // 0x7F '' 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xE0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3F,0xE0,0x00,0x00,0x00,0x00, 0 }; const int8u verdana16[] = { 16, 4, 32, 128-32, 0x00,0x00,0x11,0x00,0x22,0x00,0x33,0x00,0x54,0x00,0x65,0x00,0x86,0x00,0xA7,0x00,0xB8,0x00, 0xC9,0x00,0xDA,0x00,0xFB,0x00,0x1C,0x01,0x2D,0x01,0x3E,0x01,0x4F,0x01,0x60,0x01,0x71,0x01, 0x82,0x01,0x93,0x01,0xA4,0x01,0xB5,0x01,0xC6,0x01,0xD7,0x01,0xE8,0x01,0xF9,0x01,0x0A,0x02, 0x1B,0x02,0x2C,0x02,0x4D,0x02,0x6E,0x02,0x8F,0x02,0xA0,0x02,0xC1,0x02,0xE2,0x02,0xF3,0x02, 0x14,0x03,0x35,0x03,0x46,0x03,0x57,0x03,0x78,0x03,0x99,0x03,0xAA,0x03,0xBB,0x03,0xCC,0x03, 0xDD,0x03,0xFE,0x03,0x1F,0x04,0x40,0x04,0x51,0x04,0x72,0x04,0x93,0x04,0xB4,0x04,0xD5,0x04, 0xF6,0x04,0x17,0x05,0x38,0x05,0x59,0x05,0x7A,0x05,0x9B,0x05,0xAC,0x05,0xBD,0x05,0xCE,0x05, 0xEF,0x05,0x00,0x06,0x11,0x06,0x22,0x06,0x33,0x06,0x44,0x06,0x55,0x06,0x66,0x06,0x77,0x06, 0x88,0x06,0x99,0x06,0xAA,0x06,0xBB,0x06,0xCC,0x06,0xDD,0x06,0xFE,0x06,0x0F,0x07,0x20,0x07, 0x31,0x07,0x42,0x07,0x53,0x07,0x64,0x07,0x75,0x07,0x86,0x07,0x97,0x07,0xB8,0x07,0xC9,0x07, 0xDA,0x07,0xEB,0x07,0xFC,0x07,0x0D,0x08,0x1E,0x08,0x3F,0x08, 5, // 0x20 ' ' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x21 '!' 0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x20,0x00,0x00,0x00, 5, // 0x22 '"' 0x00,0x00,0x00,0x50,0x50,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x23 '#' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x00,0x09,0x00,0x3F,0x80,0x12,0x00,0x12,0x00,0x7F,0x00,0x24,0x00,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x24 '$' 0x00,0x00,0x00,0x10,0x10,0x3E,0x50,0x50,0x30,0x1C,0x12,0x12,0x7C,0x10,0x10,0x00, 13, // 0x25 '%' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x40,0x44,0x80,0x45,0x00,0x45,0x00,0x3A,0xE0,0x05,0x10,0x05,0x10,0x09,0x10,0x10,0xE0,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x26 '&' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x44,0x00,0x44,0x00,0x44,0x00,0x38,0x80,0x45,0x00,0x42,0x00,0x46,0x00,0x39,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 3, // 0x27 ''' 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x28 '(' 0x00,0x00,0x00,0x08,0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x10,0x08, 6, // 0x29 ')' 0x00,0x00,0x00,0x40,0x20,0x10,0x10,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x40, 9, // 0x2A '*' 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x2A,0x00,0x1C,0x00,0x2A,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x2B '+' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x7F,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x2C ',' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x40,0x00, 7, // 0x2D '-' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x2E '.' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00, 6, // 0x2F '/' 0x00,0x00,0x00,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x80,0x00, 8, // 0x30 '0' 0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00,0x00, 8, // 0x31 '1' 0x00,0x00,0x00,0x00,0x08,0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x3E,0x00,0x00,0x00, 8, // 0x32 '2' 0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x02,0x04,0x18,0x20,0x40,0x7E,0x00,0x00,0x00, 8, // 0x33 '3' 0x00,0x00,0x00,0x00,0x3C,0x42,0x02,0x02,0x1C,0x02,0x02,0x42,0x3C,0x00,0x00,0x00, 8, // 0x34 '4' 0x00,0x00,0x00,0x00,0x04,0x0C,0x14,0x24,0x44,0x7F,0x04,0x04,0x04,0x00,0x00,0x00, 8, // 0x35 '5' 0x00,0x00,0x00,0x00,0x3E,0x20,0x20,0x20,0x3C,0x02,0x02,0x42,0x3C,0x00,0x00,0x00, 8, // 0x36 '6' 0x00,0x00,0x00,0x00,0x1C,0x20,0x40,0x7C,0x42,0x42,0x42,0x42,0x3C,0x00,0x00,0x00, 8, // 0x37 '7' 0x00,0x00,0x00,0x00,0x7E,0x02,0x04,0x04,0x08,0x08,0x10,0x10,0x10,0x00,0x00,0x00, 8, // 0x38 '8' 0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x3C,0x42,0x42,0x42,0x3C,0x00,0x00,0x00, 8, // 0x39 '9' 0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x42,0x3E,0x02,0x04,0x38,0x00,0x00,0x00, 6, // 0x3A ':' 0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00, 6, // 0x3B ';' 0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00,0x20,0x20,0x20,0x40,0x00, 9, // 0x3C '<' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x0C,0x00,0x30,0x00,0x40,0x00,0x30,0x00,0x0C,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x3D '=' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x3E '>' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x01,0x00,0x06,0x00,0x18,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x3F '?' 0x00,0x00,0x00,0x00,0x38,0x44,0x04,0x08,0x10,0x10,0x00,0x10,0x10,0x00,0x00,0x00, 13, // 0x40 '@' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x10,0x40,0x27,0xA0,0x48,0x90,0x48,0x90,0x48,0x90,0x48,0x90,0x48,0x90,0x27,0xE0,0x10,0x00,0x0F,0x80,0x00,0x00, 9, // 0x41 'A' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x14,0x00,0x14,0x00,0x22,0x00,0x22,0x00,0x3E,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x42 'B' 0x00,0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x7C,0x42,0x42,0x42,0x7C,0x00,0x00,0x00, 9, // 0x43 'C' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x44 'D' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x42,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x42,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x45 'E' 0x00,0x00,0x00,0x00,0x7E,0x40,0x40,0x40,0x7E,0x40,0x40,0x40,0x7E,0x00,0x00,0x00, 8, // 0x46 'F' 0x00,0x00,0x00,0x00,0x7E,0x40,0x40,0x40,0x7C,0x40,0x40,0x40,0x40,0x00,0x00,0x00, 9, // 0x47 'G' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x47,0x00,0x41,0x00,0x21,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x48 'H' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x7F,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x49 'I' 0x00,0x00,0x00,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00,0x00, 6, // 0x4A 'J' 0x00,0x00,0x00,0x00,0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0xF0,0x00,0x00,0x00, 8, // 0x4B 'K' 0x00,0x00,0x00,0x00,0x42,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x42,0x00,0x00,0x00, 7, // 0x4C 'L' 0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7E,0x00,0x00,0x00, 11, // 0x4D 'M' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xC0,0x60,0xC0,0x51,0x40,0x51,0x40,0x4A,0x40,0x4A,0x40,0x44,0x40,0x44,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x4E 'N' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x00,0x61,0x00,0x51,0x00,0x51,0x00,0x49,0x00,0x45,0x00,0x45,0x00,0x43,0x00,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x4F 'O' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x50 'P' 0x00,0x00,0x00,0x00,0x7C,0x42,0x42,0x42,0x42,0x7C,0x40,0x40,0x40,0x00,0x00,0x00, 10, // 0x51 'Q' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x02,0x00,0x01,0x80,0x00,0x00, 9, // 0x52 'R' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x44,0x00,0x78,0x00,0x44,0x00,0x42,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x53 'S' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x41,0x00,0x40,0x00,0x40,0x00,0x3E,0x00,0x01,0x00,0x01,0x00,0x41,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x54 'T' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x55 'U' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x56 'V' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x22,0x00,0x14,0x00,0x14,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 13, // 0x57 'W' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x10,0x42,0x10,0x45,0x10,0x45,0x10,0x25,0x20,0x28,0xA0,0x28,0xA0,0x10,0x40,0x10,0x40,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x58 'X' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x14,0x00,0x08,0x00,0x14,0x00,0x22,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x59 'Y' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x22,0x00,0x22,0x00,0x14,0x00,0x14,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x5A 'Z' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x01,0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x10,0x00,0x20,0x00,0x40,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x5B '[' 0x00,0x00,0x00,0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x38,0x00, 6, // 0x5C '\' 0x00,0x00,0x00,0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x00, 6, // 0x5D ']' 0x00,0x00,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x70,0x00, 11, // 0x5E '^' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x0A,0x00,0x11,0x00,0x20,0x80,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x5F '_' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00, 8, // 0x60 '`' 0x00,0x00,0x00,0x10,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x61 'a' 0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x02,0x02,0x3E,0x42,0x42,0x3E,0x00,0x00,0x00, 8, // 0x62 'b' 0x00,0x00,0x00,0x40,0x40,0x40,0x5C,0x62,0x42,0x42,0x42,0x42,0x7C,0x00,0x00,0x00, 8, // 0x63 'c' 0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x40,0x40,0x40,0x42,0x3C,0x00,0x00,0x00, 8, // 0x64 'd' 0x00,0x00,0x00,0x02,0x02,0x02,0x3E,0x42,0x42,0x42,0x42,0x46,0x3A,0x00,0x00,0x00, 8, // 0x65 'e' 0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x7E,0x40,0x42,0x3C,0x00,0x00,0x00, 6, // 0x66 'f' 0x00,0x00,0x00,0x1C,0x20,0x20,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00, 8, // 0x67 'g' 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x42,0x42,0x42,0x42,0x46,0x3A,0x02,0x02,0x3C, 8, // 0x68 'h' 0x00,0x00,0x00,0x40,0x40,0x40,0x5C,0x62,0x42,0x42,0x42,0x42,0x42,0x00,0x00,0x00, 3, // 0x69 'i' 0x00,0x00,0x00,0x40,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, 4, // 0x6A 'j' 0x00,0x00,0x00,0x20,0x00,0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xC0, 7, // 0x6B 'k' 0x00,0x00,0x00,0x40,0x40,0x40,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x00,0x00,0x00, 3, // 0x6C 'l' 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, 11, // 0x6D 'm' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x59,0x80,0x66,0x40,0x44,0x40,0x44,0x40,0x44,0x40,0x44,0x40,0x44,0x40,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x6E 'n' 0x00,0x00,0x00,0x00,0x00,0x00,0x5C,0x62,0x42,0x42,0x42,0x42,0x42,0x00,0x00,0x00, 8, // 0x6F 'o' 0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00,0x00, 8, // 0x70 'p' 0x00,0x00,0x00,0x00,0x00,0x00,0x5C,0x62,0x42,0x42,0x42,0x42,0x7C,0x40,0x40,0x40, 8, // 0x71 'q' 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x42,0x42,0x42,0x42,0x46,0x3A,0x02,0x02,0x02, 5, // 0x72 'r' 0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x60,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, 7, // 0x73 's' 0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x40,0x40,0x38,0x04,0x04,0x78,0x00,0x00,0x00, 6, // 0x74 't' 0x00,0x00,0x00,0x00,0x20,0x20,0x78,0x20,0x20,0x20,0x20,0x20,0x18,0x00,0x00,0x00, 8, // 0x75 'u' 0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x42,0x42,0x42,0x42,0x46,0x3A,0x00,0x00,0x00, 8, // 0x76 'v' 0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x42,0x24,0x24,0x24,0x18,0x18,0x00,0x00,0x00, 11, // 0x77 'w' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x40,0x44,0x40,0x2A,0x80,0x2A,0x80,0x2A,0x80,0x11,0x00,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x78 'x' 0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x00,0x00,0x00, 8, // 0x79 'y' 0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x42,0x24,0x24,0x24,0x18,0x18,0x10,0x10,0x20, 7, // 0x7A 'z' 0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,0x00,0x00, 8, // 0x7B '{' 0x00,0x00,0x00,0x0C,0x10,0x10,0x10,0x10,0x60,0x10,0x10,0x10,0x10,0x10,0x0C,0x00, 7, // 0x7C '|' 0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00, 8, // 0x7D '}' 0x00,0x00,0x00,0x30,0x08,0x08,0x08,0x08,0x06,0x08,0x08,0x08,0x08,0x08,0x30,0x00, 11, // 0x7E '~' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x80,0x4C,0x80,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 13, // 0x7F '' 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xF0,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x3F,0xF0,0x00,0x00,0x00,0x00,0x00,0x00, 0 }; const int8u verdana16_bold[] = { 16, 4, 32, 128-32, 0x00,0x00,0x11,0x00,0x22,0x00,0x33,0x00,0x54,0x00,0x75,0x00,0xA6,0x00,0xC7,0x00,0xD8,0x00, 0xE9,0x00,0xFA,0x00,0x1B,0x01,0x3C,0x01,0x4D,0x01,0x5E,0x01,0x6F,0x01,0x90,0x01,0xB1,0x01, 0xD2,0x01,0xF3,0x01,0x14,0x02,0x35,0x02,0x56,0x02,0x77,0x02,0x98,0x02,0xB9,0x02,0xDA,0x02, 0xEB,0x02,0xFC,0x02,0x1D,0x03,0x3E,0x03,0x5F,0x03,0x70,0x03,0x91,0x03,0xB2,0x03,0xD3,0x03, 0xF4,0x03,0x15,0x04,0x36,0x04,0x57,0x04,0x78,0x04,0x99,0x04,0xAA,0x04,0xBB,0x04,0xDC,0x04, 0xED,0x04,0x0E,0x05,0x2F,0x05,0x50,0x05,0x71,0x05,0x92,0x05,0xB3,0x05,0xD4,0x05,0xE5,0x05, 0x06,0x06,0x27,0x06,0x48,0x06,0x69,0x06,0x8A,0x06,0xAB,0x06,0xBC,0x06,0xDD,0x06,0xEE,0x06, 0x0F,0x07,0x30,0x07,0x51,0x07,0x72,0x07,0x93,0x07,0xA4,0x07,0xC5,0x07,0xE6,0x07,0xF7,0x07, 0x18,0x08,0x39,0x08,0x4A,0x08,0x5B,0x08,0x6C,0x08,0x7D,0x08,0x9E,0x08,0xBF,0x08,0xE0,0x08, 0x01,0x09,0x22,0x09,0x33,0x09,0x44,0x09,0x55,0x09,0x76,0x09,0x97,0x09,0xB8,0x09,0xD9,0x09, 0xFA,0x09,0x0B,0x0A,0x2C,0x0A,0x3D,0x0A,0x5E,0x0A,0x7F,0x0A, 4, // 0x20 ' ' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x21 '!' 0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x30,0x30,0x00,0x00,0x00, 7, // 0x22 '"' 0x00,0x00,0x00,0x6C,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x23 '#' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x00,0x09,0x00,0x3F,0x80,0x3F,0x80,0x12,0x00,0x7F,0x00,0x7F,0x00,0x24,0x00,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x24 '$' 0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x3E,0x00,0x69,0x00,0x68,0x00,0x78,0x00,0x3E,0x00,0x0F,0x00,0x0B,0x00,0x4B,0x00,0x3E,0x00,0x08,0x00,0x08,0x00,0x00,0x00, 17, // 0x25 '%' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x20,0x00,0x66,0x20,0x00,0x66,0x40,0x00,0x66,0x5E,0x00,0x66,0xB3,0x00,0x3D,0x33,0x00,0x01,0x33,0x00,0x02,0x33,0x00,0x02,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x26 '&' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x66,0x00,0x66,0x00,0x66,0xC0,0x3C,0xC0,0x66,0x80,0x63,0x00,0x63,0x80,0x3C,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, 4, // 0x27 ''' 0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x28 '(' 0x00,0x00,0x00,0x0C,0x18,0x30,0x30,0x60,0x60,0x60,0x60,0x60,0x30,0x30,0x18,0x0C, 7, // 0x29 ')' 0x00,0x00,0x00,0x60,0x30,0x18,0x18,0x0C,0x0C,0x0C,0x0C,0x0C,0x18,0x18,0x30,0x60, 9, // 0x2A '*' 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x49,0x00,0x2A,0x00,0x1C,0x00,0x2A,0x00,0x49,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x2B '+' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x3F,0x80,0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x2C ',' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x60,0x60,0xC0,0xC0, 7, // 0x2D '-' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x2E '.' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00, 9, // 0x2F '/' 0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x03,0x00,0x06,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x30,0x00,0x30,0x00,0x60,0x00,0x60,0x00,0x00,0x00, 9, // 0x30 '0' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x31 '1' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x3C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x32 '2' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x03,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x33 '3' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x03,0x00,0x0E,0x00,0x03,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x34 '4' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x0E,0x00,0x16,0x00,0x26,0x00,0x46,0x00,0x7F,0x80,0x06,0x00,0x06,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x35 '5' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x30,0x00,0x30,0x00,0x3E,0x00,0x03,0x00,0x03,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x36 '6' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x30,0x00,0x60,0x00,0x7E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x37 '7' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x03,0x00,0x03,0x00,0x06,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x38 '8' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x39 '9' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3F,0x00,0x03,0x00,0x06,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x3A ':' 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00, 5, // 0x3B ';' 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x38,0x30,0x30,0x60,0x60, 11, // 0x3C '<' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x03,0x00,0x0C,0x00,0x30,0x00,0x40,0x00,0x30,0x00,0x0C,0x00,0x03,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x3D '=' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x80,0x00,0x00,0x00,0x00,0x3F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x3E '>' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x18,0x00,0x06,0x00,0x01,0x80,0x00,0x40,0x01,0x80,0x06,0x00,0x18,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x3F '?' 0x00,0x00,0x00,0x00,0x3C,0x66,0x06,0x0C,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00, 13, // 0x40 '@' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x30,0x60,0x27,0xA0,0x4D,0x90,0x4D,0x90,0x4D,0x90,0x4D,0x90,0x27,0xE0,0x30,0x00,0x0F,0x80,0x00,0x00,0x00,0x00, 10, // 0x41 'A' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x1E,0x00,0x1E,0x00,0x33,0x00,0x33,0x00,0x7F,0x80,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x42 'B' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x7F,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x43 'C' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x31,0x80,0x61,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x61,0x80,0x31,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x44 'D' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x63,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x45 'E' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x46 'F' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x47 'G' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x31,0x80,0x61,0x80,0x60,0x00,0x60,0x00,0x63,0x80,0x61,0x80,0x31,0x80,0x1F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x48 'H' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x7F,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x49 'I' 0x00,0x00,0x00,0x00,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00, 7, // 0x4A 'J' 0x00,0x00,0x00,0x00,0x7C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0xF8,0x00,0x00,0x00, 9, // 0x4B 'K' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x66,0x00,0x6C,0x00,0x78,0x00,0x78,0x00,0x6C,0x00,0x66,0x00,0x63,0x00,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x4C 'L' 0x00,0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x7F,0x00,0x00,0x00, 12, // 0x4D 'M' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0xE0,0x70,0xE0,0x59,0x60,0x59,0x60,0x4E,0x60,0x4E,0x60,0x44,0x60,0x44,0x60,0x40,0x60,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x4E 'N' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x80,0x70,0x80,0x58,0x80,0x58,0x80,0x4C,0x80,0x46,0x80,0x46,0x80,0x43,0x80,0x43,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x4F 'O' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x31,0x80,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x31,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x50 'P' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x7E,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x51 'Q' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x31,0x80,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x31,0x80,0x1F,0x00,0x03,0x00,0x01,0xC0,0x00,0x00, 9, // 0x52 'R' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x7E,0x00,0x6C,0x00,0x66,0x00,0x63,0x00,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x53 'S' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x70,0x00,0x3E,0x00,0x07,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x54 'T' 0x00,0x00,0x00,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00, 10, // 0x55 'U' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x56 'V' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x33,0x00,0x1E,0x00,0x1E,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 14, // 0x57 'W' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x18,0x63,0x18,0x63,0x18,0x33,0x30,0x37,0xB0,0x34,0xB0,0x1C,0xE0,0x18,0x60,0x18,0x60,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x58 'X' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x33,0x00,0x33,0x00,0x1E,0x00,0x0C,0x00,0x1E,0x00,0x33,0x00,0x33,0x00,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x59 'Y' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x5A 'Z' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x30,0x00,0x30,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x5B '[' 0x00,0x00,0x00,0x78,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x78,0x00, 9, // 0x5C '\' 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x30,0x00,0x30,0x00,0x18,0x00,0x18,0x00,0x0C,0x00,0x0C,0x00,0x06,0x00,0x06,0x00,0x03,0x00,0x03,0x00,0x00,0x00, 6, // 0x5D ']' 0x00,0x00,0x00,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x78,0x00, 10, // 0x5E '^' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 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,0x00,0xFF,0x80,0x00,0x00, 9, // 0x60 '`' 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x61 'a' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x03,0x00,0x3F,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x62 'b' 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x6E,0x00,0x73,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x63 'c' 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x60,0x60,0x60,0x63,0x3E,0x00,0x00,0x00, 9, // 0x64 'd' 0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x3F,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x67,0x00,0x3B,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x65 'e' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x7F,0x00,0x60,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x66 'f' 0x00,0x00,0x00,0x38,0x60,0x60,0xF8,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00, 9, // 0x67 'g' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x67,0x00,0x3B,0x00,0x03,0x00,0x03,0x00,0x3E,0x00, 9, // 0x68 'h' 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x6E,0x00,0x73,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 4, // 0x69 'i' 0x00,0x00,0x00,0x60,0x60,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00, 5, // 0x6A 'j' 0x00,0x00,0x00,0x30,0x30,0x00,0x70,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0xE0, 8, // 0x6B 'k' 0x00,0x00,0x00,0x60,0x60,0x60,0x66,0x6C,0x78,0x78,0x6C,0x66,0x63,0x00,0x00,0x00, 4, // 0x6C 'l' 0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00, 14, // 0x6D 'm' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6E,0x70,0x73,0x98,0x63,0x18,0x63,0x18,0x63,0x18,0x63,0x18,0x63,0x18,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x6E 'n' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6E,0x00,0x73,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x6F 'o' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x70 'p' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6E,0x00,0x73,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x7E,0x00,0x60,0x00,0x60,0x00,0x60,0x00, 9, // 0x71 'q' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x67,0x00,0x3B,0x00,0x03,0x00,0x03,0x00,0x03,0x00, 6, // 0x72 'r' 0x00,0x00,0x00,0x00,0x00,0x00,0x6C,0x7C,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00, 8, // 0x73 's' 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x60,0x70,0x3C,0x0E,0x06,0x7C,0x00,0x00,0x00, 6, // 0x74 't' 0x00,0x00,0x00,0x00,0x60,0x60,0xF8,0x60,0x60,0x60,0x60,0x60,0x38,0x00,0x00,0x00, 9, // 0x75 'u' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x67,0x00,0x3B,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x76 'v' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x36,0x00,0x36,0x00,0x1C,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 12, // 0x77 'w' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x60,0x66,0x60,0x66,0x60,0x69,0x60,0x39,0xC0,0x30,0xC0,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x78 'x' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x36,0x00,0x1C,0x00,0x36,0x00,0x63,0x00,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x79 'y' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x36,0x00,0x36,0x00,0x1C,0x00,0x1C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00, 8, // 0x7A 'z' 0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x06,0x0C,0x18,0x30,0x60,0x7E,0x00,0x00,0x00, 9, // 0x7B '{' 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x70,0x00,0x18,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x07,0x00,0x00,0x00, 8, // 0x7C '|' 0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00, 9, // 0x7D '}' 0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x0C,0x00,0x07,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x70,0x00,0x00,0x00, 11, // 0x7E '~' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x40,0x44,0x40,0x44,0x40,0x43,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 13, // 0x7F '' 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xF0,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x3F,0xF0,0x00,0x00,0x00,0x00,0x00,0x00, 0 }; const int8u verdana17[] = { 17, 4, 32, 128-32, 0x00,0x00,0x12,0x00,0x24,0x00,0x36,0x00,0x59,0x00,0x7C,0x00,0x9F,0x00,0xC2,0x00,0xD4,0x00, 0xE6,0x00,0xF8,0x00,0x1B,0x01,0x3E,0x01,0x50,0x01,0x62,0x01,0x74,0x01,0x86,0x01,0xA9,0x01, 0xCC,0x01,0xEF,0x01,0x12,0x02,0x35,0x02,0x58,0x02,0x7B,0x02,0x9E,0x02,0xC1,0x02,0xE4,0x02, 0xF6,0x02,0x08,0x03,0x2B,0x03,0x4E,0x03,0x71,0x03,0x83,0x03,0xA6,0x03,0xC9,0x03,0xEC,0x03, 0x0F,0x04,0x32,0x04,0x55,0x04,0x67,0x04,0x8A,0x04,0xAD,0x04,0xBF,0x04,0xD1,0x04,0xF4,0x04, 0x06,0x05,0x29,0x05,0x4C,0x05,0x6F,0x05,0x81,0x05,0xA4,0x05,0xC7,0x05,0xEA,0x05,0x0D,0x06, 0x30,0x06,0x53,0x06,0x76,0x06,0x99,0x06,0xBC,0x06,0xDF,0x06,0xF1,0x06,0x03,0x07,0x15,0x07, 0x38,0x07,0x5B,0x07,0x7E,0x07,0x90,0x07,0xB3,0x07,0xC5,0x07,0xE8,0x07,0xFA,0x07,0x0C,0x08, 0x2F,0x08,0x52,0x08,0x64,0x08,0x76,0x08,0x88,0x08,0x9A,0x08,0xBD,0x08,0xE0,0x08,0x03,0x09, 0x26,0x09,0x49,0x09,0x5B,0x09,0x6D,0x09,0x7F,0x09,0xA2,0x09,0xB4,0x09,0xD7,0x09,0xFA,0x09, 0x0C,0x0A,0x1E,0x0A,0x41,0x0A,0x53,0x0A,0x76,0x0A,0x99,0x0A, 5, // 0x20 ' ' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x21 '!' 0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x20,0x00,0x00,0x00, 6, // 0x22 '"' 0x00,0x00,0x00,0x48,0x48,0x48,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x23 '#' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x80,0x04,0x80,0x09,0x00,0x3F,0xC0,0x09,0x00,0x12,0x00,0x7F,0x80,0x12,0x00,0x24,0x00,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x24 '$' 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x3E,0x00,0x49,0x00,0x48,0x00,0x48,0x00,0x3E,0x00,0x09,0x00,0x09,0x00,0x49,0x00,0x3E,0x00,0x08,0x00,0x08,0x00,0x00,0x00, 15, // 0x25 '%' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x20,0x44,0x40,0x44,0x80,0x44,0x80,0x45,0x38,0x39,0x44,0x02,0x44,0x04,0x44,0x04,0x44,0x08,0x38,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x26 '&' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x42,0x00,0x42,0x00,0x44,0x00,0x38,0x80,0x44,0x80,0x42,0x80,0x41,0x00,0x22,0x80,0x1C,0x40,0x00,0x00,0x00,0x00,0x00,0x00, 4, // 0x27 ''' 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x28 '(' 0x00,0x00,0x00,0x08,0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x10,0x08, 6, // 0x29 ')' 0x00,0x00,0x00,0x40,0x20,0x10,0x10,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x40, 9, // 0x2A '*' 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x49,0x00,0x2A,0x00,0x1C,0x00,0x2A,0x00,0x49,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x2B '+' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x7F,0xC0,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x2C ',' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x40,0x00, 7, // 0x2D '-' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x2E '.' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00, 6, // 0x2F '/' 0x00,0x00,0x00,0x04,0x08,0x08,0x08,0x10,0x10,0x20,0x20,0x20,0x40,0x40,0x80,0x80,0x00, 9, // 0x30 '0' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x22,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x31 '1' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x38,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x32 '2' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x41,0x00,0x01,0x00,0x01,0x00,0x02,0x00,0x0C,0x00,0x10,0x00,0x20,0x00,0x40,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x33 '3' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x41,0x00,0x01,0x00,0x02,0x00,0x1C,0x00,0x02,0x00,0x01,0x00,0x01,0x00,0x42,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x34 '4' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x06,0x00,0x0A,0x00,0x12,0x00,0x22,0x00,0x42,0x00,0x7F,0x80,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x35 '5' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x7C,0x00,0x02,0x00,0x01,0x00,0x01,0x00,0x42,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x36 '6' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x30,0x00,0x20,0x00,0x40,0x00,0x7C,0x00,0x42,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x37 '7' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x04,0x00,0x04,0x00,0x08,0x00,0x10,0x00,0x10,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x38 '8' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x3E,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x39 '9' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x22,0x00,0x41,0x00,0x41,0x00,0x21,0x00,0x1F,0x00,0x01,0x00,0x02,0x00,0x06,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x3A ':' 0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00, 6, // 0x3B ';' 0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x40,0x00, 11, // 0x3C '<' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x06,0x00,0x18,0x00,0x60,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x3D '=' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xC0,0x00,0x00,0x00,0x00,0x3F,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x3E '>' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x0C,0x00,0x03,0x00,0x00,0xC0,0x00,0xC0,0x03,0x00,0x0C,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x3F '?' 0x00,0x00,0x00,0x00,0x3C,0x42,0x02,0x02,0x0C,0x10,0x10,0x00,0x10,0x10,0x00,0x00,0x00, 14, // 0x40 '@' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xC0,0x18,0x20,0x20,0x10,0x27,0xC8,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x27,0xF0,0x20,0x00,0x18,0x00,0x07,0xC0,0x00,0x00, 10, // 0x41 'A' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x12,0x00,0x12,0x00,0x21,0x00,0x21,0x00,0x21,0x00,0x7F,0x80,0x40,0x80,0x80,0x40,0x80,0x40,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x42 'B' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x7E,0x00,0x41,0x00,0x40,0x80,0x40,0x80,0x41,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x43 'C' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x30,0x80,0x20,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x30,0x80,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x44 'D' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x41,0x80,0x40,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x41,0x80,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x45 'E' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x7F,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x46 'F' 0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x7E,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, 11, // 0x47 'G' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x30,0xC0,0x20,0x40,0x40,0x00,0x40,0x00,0x43,0xC0,0x40,0x40,0x20,0x40,0x30,0x40,0x0F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x48 'H' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x7F,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x49 'I' 0x00,0x00,0x00,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00,0x00, 6, // 0x4A 'J' 0x00,0x00,0x00,0x00,0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0xF0,0x00,0x00,0x00, 10, // 0x4B 'K' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x42,0x00,0x44,0x00,0x48,0x00,0x50,0x00,0x68,0x00,0x44,0x00,0x42,0x00,0x41,0x00,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x4C 'L' 0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7F,0x00,0x00,0x00, 11, // 0x4D 'M' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xC0,0x60,0xC0,0x51,0x40,0x51,0x40,0x4A,0x40,0x4A,0x40,0x44,0x40,0x44,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x4E 'N' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x80,0x60,0x80,0x50,0x80,0x48,0x80,0x48,0x80,0x44,0x80,0x44,0x80,0x42,0x80,0x41,0x80,0x41,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x4F 'O' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x31,0x80,0x20,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x20,0x80,0x31,0x80,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x50 'P' 0x00,0x00,0x00,0x00,0x7C,0x42,0x41,0x41,0x42,0x7C,0x40,0x40,0x40,0x40,0x00,0x00,0x00, 11, // 0x51 'Q' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x31,0x80,0x20,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x20,0x80,0x31,0x80,0x0E,0x00,0x02,0x00,0x02,0x00,0x01,0xC0, 10, // 0x52 'R' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x44,0x00,0x78,0x00,0x44,0x00,0x42,0x00,0x41,0x00,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x53 'S' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x20,0x80,0x40,0x00,0x40,0x00,0x38,0x00,0x07,0x00,0x00,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x54 'T' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x80,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x55 'U' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x56 'V' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x80,0x40,0x40,0x80,0x40,0x80,0x21,0x00,0x21,0x00,0x21,0x00,0x12,0x00,0x12,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 15, // 0x57 'W' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x04,0x41,0x04,0x22,0x88,0x22,0x88,0x22,0x88,0x14,0x50,0x14,0x50,0x14,0x50,0x08,0x20,0x08,0x20,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x58 'X' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x21,0x00,0x12,0x00,0x12,0x00,0x0C,0x00,0x0C,0x00,0x12,0x00,0x12,0x00,0x21,0x00,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x59 'Y' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x41,0x00,0x22,0x00,0x22,0x00,0x14,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x5A 'Z' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x00,0x80,0x01,0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x10,0x00,0x20,0x00,0x40,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x5B '[' 0x00,0x00,0x00,0x3C,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3C, 6, // 0x5C '\' 0x00,0x00,0x00,0x80,0x40,0x40,0x40,0x20,0x20,0x10,0x10,0x10,0x08,0x08,0x08,0x04,0x00, 6, // 0x5D ']' 0x00,0x00,0x00,0x78,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x78, 11, // 0x5E '^' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x0A,0x00,0x11,0x00,0x20,0x80,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 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,0x00,0x00,0x00,0xFF,0x80,0x00,0x00, 9, // 0x60 '`' 0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x61 'a' 0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x22,0x02,0x3E,0x42,0x42,0x46,0x3A,0x00,0x00,0x00, 9, // 0x62 'b' 0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x5C,0x00,0x62,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x42,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x63 'c' 0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x22,0x40,0x40,0x40,0x40,0x22,0x1C,0x00,0x00,0x00, 9, // 0x64 'd' 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x1F,0x00,0x21,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x23,0x00,0x1D,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x65 'e' 0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x24,0x42,0x7E,0x40,0x40,0x22,0x1C,0x00,0x00,0x00, 6, // 0x66 'f' 0x00,0x00,0x00,0x1C,0x20,0x20,0x7C,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00, 9, // 0x67 'g' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x21,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x23,0x00,0x1D,0x00,0x01,0x00,0x22,0x00,0x1C,0x00, 9, // 0x68 'h' 0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x5E,0x00,0x61,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 3, // 0x69 'i' 0x00,0x00,0x00,0x00,0x40,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, 5, // 0x6A 'j' 0x00,0x00,0x00,0x00,0x10,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xE0, 8, // 0x6B 'k' 0x00,0x00,0x00,0x40,0x40,0x40,0x42,0x44,0x48,0x50,0x70,0x48,0x44,0x42,0x00,0x00,0x00, 3, // 0x6C 'l' 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, 13, // 0x6D 'm' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5C,0xE0,0x63,0x10,0x42,0x10,0x42,0x10,0x42,0x10,0x42,0x10,0x42,0x10,0x42,0x10,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x6E 'n' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5E,0x00,0x61,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x6F 'o' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x22,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x70 'p' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5C,0x00,0x62,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x42,0x00,0x7C,0x00,0x40,0x00,0x40,0x00,0x40,0x00, 9, // 0x71 'q' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x21,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x23,0x00,0x1D,0x00,0x01,0x00,0x01,0x00,0x01,0x00, 6, // 0x72 'r' 0x00,0x00,0x00,0x00,0x00,0x00,0x5C,0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, 8, // 0x73 's' 0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x40,0x30,0x0C,0x02,0x42,0x3C,0x00,0x00,0x00, 6, // 0x74 't' 0x00,0x00,0x00,0x00,0x20,0x20,0x7C,0x20,0x20,0x20,0x20,0x20,0x20,0x1C,0x00,0x00,0x00, 9, // 0x75 'u' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x43,0x00,0x3D,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x76 'v' 0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x42,0x24,0x24,0x24,0x18,0x18,0x18,0x00,0x00,0x00, 11, // 0x77 'w' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x40,0x44,0x40,0x2A,0x80,0x2A,0x80,0x2A,0x80,0x2A,0x80,0x11,0x00,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x78 'x' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x22,0x00,0x14,0x00,0x08,0x00,0x08,0x00,0x14,0x00,0x22,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x79 'y' 0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x42,0x24,0x24,0x24,0x18,0x18,0x18,0x10,0x10,0x20, 8, // 0x7A 'z' 0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x02,0x04,0x08,0x10,0x20,0x40,0x7E,0x00,0x00,0x00, 9, // 0x7B '{' 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x10,0x00,0x60,0x00,0x10,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x07,0x00, 6, // 0x7C '|' 0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, 9, // 0x7D '}' 0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x04,0x00,0x03,0x00,0x04,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x70,0x00, 11, // 0x7E '~' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x40,0x44,0x40,0x44,0x40,0x43,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 14, // 0x7F '' 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xF8,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x3F,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, 0 }; const int8u verdana17_bold[] = { 17, 4, 32, 128-32, 0x00,0x00,0x12,0x00,0x24,0x00,0x36,0x00,0x59,0x00,0x7C,0x00,0xB0,0x00,0xD3,0x00,0xE5,0x00, 0xF7,0x00,0x09,0x01,0x2C,0x01,0x4F,0x01,0x61,0x01,0x73,0x01,0x85,0x01,0xA8,0x01,0xCB,0x01, 0xEE,0x01,0x11,0x02,0x34,0x02,0x57,0x02,0x7A,0x02,0x9D,0x02,0xC0,0x02,0xE3,0x02,0x06,0x03, 0x18,0x03,0x2A,0x03,0x4D,0x03,0x70,0x03,0x93,0x03,0xB6,0x03,0xD9,0x03,0xFC,0x03,0x1F,0x04, 0x42,0x04,0x65,0x04,0x88,0x04,0xAB,0x04,0xCE,0x04,0xF1,0x04,0x03,0x05,0x15,0x05,0x38,0x05, 0x5B,0x05,0x7E,0x05,0xA1,0x05,0xC4,0x05,0xE7,0x05,0x0A,0x06,0x2D,0x06,0x50,0x06,0x73,0x06, 0x96,0x06,0xB9,0x06,0xDC,0x06,0xFF,0x06,0x22,0x07,0x45,0x07,0x57,0x07,0x7A,0x07,0x8C,0x07, 0xAF,0x07,0xD2,0x07,0xF5,0x07,0x18,0x08,0x3B,0x08,0x4D,0x08,0x70,0x08,0x93,0x08,0xA5,0x08, 0xC8,0x08,0xEB,0x08,0xFD,0x08,0x0F,0x09,0x32,0x09,0x44,0x09,0x67,0x09,0x8A,0x09,0xAD,0x09, 0xD0,0x09,0xF3,0x09,0x05,0x0A,0x17,0x0A,0x29,0x0A,0x4C,0x0A,0x6F,0x0A,0x92,0x0A,0xB5,0x0A, 0xD8,0x0A,0xEA,0x0A,0x0D,0x0B,0x1F,0x0B,0x42,0x0B,0x65,0x0B, 5, // 0x20 ' ' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x21 '!' 0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x30,0x30,0x00,0x00,0x00, 8, // 0x22 '"' 0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 12, // 0x23 '#' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x40,0x04,0x40,0x3F,0xE0,0x3F,0xE0,0x08,0x80,0x11,0x00,0x7F,0xC0,0x7F,0xC0,0x22,0x00,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x24 '$' 0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x1F,0x00,0x34,0x80,0x64,0x00,0x74,0x00,0x3C,0x00,0x0F,0x00,0x0B,0x80,0x09,0x80,0x4B,0x00,0x3E,0x00,0x08,0x00,0x08,0x00,0x00,0x00, 18, // 0x25 '%' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x08,0x00,0x66,0x10,0x00,0x66,0x20,0x00,0x66,0x2F,0x00,0x66,0x59,0x80,0x66,0x99,0x80,0x3D,0x19,0x80,0x01,0x19,0x80,0x02,0x19,0x80,0x04,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 12, // 0x26 '&' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x33,0x00,0x36,0x00,0x1C,0x60,0x36,0x60,0x63,0x60,0x61,0xC0,0x31,0xC0,0x1F,0x60,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x27 ''' 0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x28 '(' 0x00,0x00,0x00,0x0C,0x18,0x30,0x30,0x60,0x60,0x60,0x60,0x60,0x60,0x30,0x30,0x18,0x0C, 8, // 0x29 ')' 0x00,0x00,0x00,0x30,0x18,0x0C,0x0C,0x06,0x06,0x06,0x06,0x06,0x06,0x0C,0x0C,0x18,0x30, 10, // 0x2A '*' 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x49,0x00,0x2A,0x00,0x1C,0x00,0x2A,0x00,0x49,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 12, // 0x2B '+' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x7F,0xC0,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x2C ',' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x60,0x60,0xC0,0xC0,0x00, 7, // 0x2D '-' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x2E '.' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x00,0x00,0x00, 10, // 0x2F '/' 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x03,0x00,0x03,0x00,0x06,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x30,0x00,0x30,0x00,0x60,0x00,0x60,0x00,0x00,0x00, 10, // 0x30 '0' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x31 '1' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x3C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x32 '2' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x61,0x80,0x61,0x80,0x01,0x80,0x03,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x33 '3' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x61,0x80,0x61,0x80,0x01,0x80,0x0F,0x00,0x03,0x00,0x01,0x80,0x61,0x80,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x34 '4' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x07,0x00,0x0B,0x00,0x13,0x00,0x23,0x00,0x43,0x00,0x7F,0xC0,0x03,0x00,0x03,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x35 '5' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x80,0x30,0x00,0x30,0x00,0x3E,0x00,0x03,0x00,0x01,0x80,0x01,0x80,0x61,0x80,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x36 '6' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x38,0x00,0x30,0x00,0x6E,0x00,0x73,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x37 '7' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x01,0x80,0x03,0x00,0x03,0x00,0x06,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x38 '8' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x3F,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x39 '9' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x80,0x1D,0x80,0x03,0x00,0x07,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x3A ':' 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x00,0x00,0x30,0x30,0x30,0x00,0x00,0x00, 6, // 0x3B ';' 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x00,0x00,0x38,0x30,0x30,0x60,0x60,0x00, 12, // 0x3C '<' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x03,0x00,0x0C,0x00,0x30,0x00,0x40,0x00,0x30,0x00,0x0C,0x00,0x03,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, 12, // 0x3D '=' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 12, // 0x3E '>' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x01,0x80,0x00,0x40,0x01,0x80,0x06,0x00,0x18,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x3F '?' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x03,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x00,0x00,0x18,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 14, // 0x40 '@' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xC0,0x18,0x20,0x20,0x10,0x27,0xC8,0x4C,0xC8,0x4C,0xC8,0x4C,0xC8,0x4C,0xC8,0x27,0xF0,0x20,0x00,0x18,0x00,0x07,0xC0,0x00,0x00, 11, // 0x41 'A' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x1B,0x00,0x1B,0x00,0x31,0x80,0x3F,0x80,0x31,0x80,0x60,0xC0,0x60,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x42 'B' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x7F,0x00,0x61,0x80,0x60,0xC0,0x60,0xC0,0x61,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x43 'C' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x30,0xC0,0x30,0xC0,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x30,0xC0,0x30,0xC0,0x0F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x44 'D' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x61,0x80,0x61,0x80,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x61,0x80,0x61,0x80,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x45 'E' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x46 'F' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x47 'G' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x30,0xC0,0x30,0xC0,0x60,0x00,0x60,0x00,0x63,0xC0,0x60,0xC0,0x30,0xC0,0x30,0xC0,0x0F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x48 'H' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x7F,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x49 'I' 0x00,0x00,0x00,0x00,0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00,0x00, 8, // 0x4A 'J' 0x00,0x00,0x00,0x00,0x3E,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0C,0xF8,0x00,0x00,0x00, 11, // 0x4B 'K' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xC0,0x61,0x80,0x63,0x00,0x66,0x00,0x6C,0x00,0x7C,0x00,0x76,0x00,0x63,0x00,0x61,0x80,0x60,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x4C 'L' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 13, // 0x4D 'M' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x70,0x70,0x70,0x70,0xF0,0x58,0xB0,0x59,0xB0,0x4D,0x30,0x4F,0x30,0x46,0x30,0x46,0x30,0x40,0x30,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x4E 'N' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x40,0x70,0x40,0x58,0x40,0x4C,0x40,0x4C,0x40,0x46,0x40,0x43,0x40,0x43,0x40,0x41,0xC0,0x40,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, 12, // 0x4F 'O' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x30,0xC0,0x30,0xC0,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x30,0xC0,0x30,0xC0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x50 'P' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x63,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x00,0x7E,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 12, // 0x51 'Q' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x30,0xC0,0x30,0xC0,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x30,0xC0,0x30,0xC0,0x0F,0x80,0x03,0x00,0x03,0x00,0x01,0xE0, 11, // 0x52 'R' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x61,0x80,0x60,0xC0,0x60,0xC0,0x61,0x80,0x7F,0x00,0x63,0x00,0x61,0x80,0x60,0xC0,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x53 'S' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x31,0x80,0x61,0x80,0x60,0x00,0x3E,0x00,0x1F,0x00,0x01,0x80,0x61,0x80,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x54 'T' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x55 'U' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x31,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x56 'V' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x31,0x80,0x31,0x80,0x31,0x80,0x1B,0x00,0x1B,0x00,0x0E,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 16, // 0x57 'W' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x86,0x61,0x86,0x63,0xC6,0x32,0x4C,0x36,0x6C,0x36,0x6C,0x34,0x2C,0x1C,0x38,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x58 'X' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xC0,0x31,0x80,0x31,0x80,0x1B,0x00,0x0E,0x00,0x0E,0x00,0x1B,0x00,0x31,0x80,0x31,0x80,0x60,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x59 'Y' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x5A 'Z' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x01,0x80,0x03,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x60,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x5B '[' 0x00,0x00,0x00,0x3E,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3E, 10, // 0x5C '\' 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x30,0x00,0x30,0x00,0x18,0x00,0x18,0x00,0x0C,0x00,0x06,0x00,0x06,0x00,0x03,0x00,0x03,0x00,0x01,0x80,0x01,0x80,0x00,0x00, 8, // 0x5D ']' 0x00,0x00,0x00,0x7C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x7C, 12, // 0x5E '^' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x0E,0x00,0x1B,0x00,0x31,0x80,0x60,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 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,0x00,0x00,0x00,0xFF,0xC0,0x00,0x00, 10, // 0x60 '`' 0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x61 'a' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x03,0x00,0x03,0x00,0x3F,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x62 'b' 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x6E,0x00,0x73,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x63 'c' 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x33,0x60,0x60,0x60,0x60,0x33,0x1E,0x00,0x00,0x00, 10, // 0x64 'd' 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x01,0x80,0x1F,0x80,0x31,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x80,0x1D,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x65 'e' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x63,0x00,0x7F,0x00,0x60,0x00,0x60,0x00,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x66 'f' 0x00,0x00,0x00,0x1C,0x30,0x30,0x7C,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x00, 10, // 0x67 'g' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x80,0x31,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x80,0x1D,0x80,0x01,0x80,0x03,0x00,0x3E,0x00, 10, // 0x68 'h' 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x6F,0x00,0x71,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 4, // 0x69 'i' 0x00,0x00,0x00,0x60,0x60,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00, 6, // 0x6A 'j' 0x00,0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF0, 9, // 0x6B 'k' 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x63,0x00,0x66,0x00,0x6C,0x00,0x78,0x00,0x7C,0x00,0x66,0x00,0x63,0x00,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 4, // 0x6C 'l' 0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00, 14, // 0x6D 'm' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6E,0x70,0x73,0x98,0x63,0x18,0x63,0x18,0x63,0x18,0x63,0x18,0x63,0x18,0x63,0x18,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x6E 'n' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6F,0x00,0x71,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x6F 'o' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x70 'p' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6E,0x00,0x73,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x00,0x7E,0x00,0x60,0x00,0x60,0x00,0x60,0x00, 10, // 0x71 'q' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x80,0x31,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x80,0x1D,0x80,0x01,0x80,0x01,0x80,0x01,0x80, 7, // 0x72 'r' 0x00,0x00,0x00,0x00,0x00,0x00,0x6E,0x7E,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00, 8, // 0x73 's' 0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x62,0x60,0x7C,0x3E,0x06,0x46,0x3C,0x00,0x00,0x00, 6, // 0x74 't' 0x00,0x00,0x00,0x00,0x60,0x60,0xFC,0x60,0x60,0x60,0x60,0x60,0x60,0x3C,0x00,0x00,0x00, 10, // 0x75 'u' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x80,0x3D,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x76 'v' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x36,0x00,0x36,0x00,0x36,0x00,0x1C,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 14, // 0x77 'w' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x18,0x63,0x18,0x33,0x30,0x37,0xB0,0x34,0xB0,0x1C,0xE0,0x1C,0xE0,0x0C,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x78 'x' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x36,0x00,0x1C,0x00,0x1C,0x00,0x36,0x00,0x63,0x00,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x79 'y' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x36,0x00,0x36,0x00,0x36,0x00,0x1C,0x00,0x1C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00, 8, // 0x7A 'z' 0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x06,0x0C,0x18,0x18,0x30,0x60,0x7E,0x00,0x00,0x00, 10, // 0x7B '{' 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x80,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x70,0x00,0x18,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x07,0x80, 8, // 0x7C '|' 0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, 10, // 0x7D '}' 0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x06,0x00,0x03,0x80,0x06,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x78,0x00, 12, // 0x7E '~' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x20,0x24,0x20,0x46,0x20,0x42,0x40,0x41,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 14, // 0x7F '' 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xF8,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x3F,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, 0 }; const int8u verdana18[] = { 18, 4, 32, 128-32, 0x00,0x00,0x13,0x00,0x26,0x00,0x39,0x00,0x5E,0x00,0x83,0x00,0xA8,0x00,0xCD,0x00,0xE0,0x00, 0xF3,0x00,0x06,0x01,0x2B,0x01,0x50,0x01,0x63,0x01,0x76,0x01,0x89,0x01,0x9C,0x01,0xC1,0x01, 0xE6,0x01,0x0B,0x02,0x30,0x02,0x55,0x02,0x7A,0x02,0x9F,0x02,0xC4,0x02,0xE9,0x02,0x0E,0x03, 0x21,0x03,0x34,0x03,0x59,0x03,0x7E,0x03,0xA3,0x03,0xB6,0x03,0xDB,0x03,0x00,0x04,0x25,0x04, 0x4A,0x04,0x6F,0x04,0x94,0x04,0xB9,0x04,0xDE,0x04,0x03,0x05,0x16,0x05,0x29,0x05,0x4E,0x05, 0x61,0x05,0x86,0x05,0xAB,0x05,0xD0,0x05,0xF5,0x05,0x1A,0x06,0x3F,0x06,0x64,0x06,0x89,0x06, 0xAE,0x06,0xD3,0x06,0xF8,0x06,0x1D,0x07,0x42,0x07,0x67,0x07,0x7A,0x07,0x8D,0x07,0xA0,0x07, 0xC5,0x07,0xEA,0x07,0x0F,0x08,0x34,0x08,0x59,0x08,0x6C,0x08,0x91,0x08,0xB6,0x08,0xC9,0x08, 0xEE,0x08,0x13,0x09,0x26,0x09,0x39,0x09,0x5E,0x09,0x71,0x09,0x96,0x09,0xBB,0x09,0xE0,0x09, 0x05,0x0A,0x2A,0x0A,0x3D,0x0A,0x50,0x0A,0x63,0x0A,0x88,0x0A,0xAD,0x0A,0xD2,0x0A,0xF7,0x0A, 0x1C,0x0B,0x41,0x0B,0x66,0x0B,0x79,0x0B,0x9E,0x0B,0xC3,0x0B, 5, // 0x20 ' ' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x21 '!' 0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x20,0x00,0x00,0x00, 7, // 0x22 '"' 0x00,0x00,0x00,0x48,0x48,0x48,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 12, // 0x23 '#' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x80,0x04,0x80,0x09,0x00,0x3F,0xC0,0x09,0x00,0x11,0x00,0x12,0x00,0x7F,0x80,0x12,0x00,0x24,0x00,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x24 '$' 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x3E,0x00,0x49,0x00,0x48,0x00,0x48,0x00,0x38,0x00,0x0E,0x00,0x09,0x00,0x09,0x00,0x49,0x00,0x3E,0x00,0x08,0x00,0x08,0x00,0x08,0x00, 16, // 0x25 '%' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x20,0x44,0x40,0x44,0x40,0x44,0x80,0x44,0x80,0x38,0x9C,0x01,0x22,0x01,0x22,0x02,0x22,0x02,0x22,0x04,0x1C,0x00,0x00,0x00,0x00,0x00,0x00, 12, // 0x26 '&' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x21,0x00,0x21,0x00,0x1E,0x40,0x24,0x40,0x42,0x40,0x41,0x40,0x40,0x80,0x21,0x40,0x1E,0x20,0x00,0x00,0x00,0x00,0x00,0x00, 4, // 0x27 ''' 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x28 '(' 0x00,0x00,0x00,0x08,0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x10,0x08, 7, // 0x29 ')' 0x00,0x00,0x00,0x20,0x10,0x08,0x08,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x08,0x08,0x10,0x20, 10, // 0x2A '*' 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x49,0x00,0x2A,0x00,0x1C,0x00,0x2A,0x00,0x49,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 12, // 0x2B '+' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x3F,0xE0,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x2C ',' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x40,0x40, 7, // 0x2D '-' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x2E '.' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00, 7, // 0x2F '/' 0x00,0x00,0x00,0x02,0x04,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x40,0x80,0x00, 10, // 0x30 '0' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x31 '1' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x1C,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x32 '2' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x41,0x00,0x00,0x80,0x00,0x80,0x00,0x80,0x01,0x00,0x02,0x00,0x0C,0x00,0x30,0x00,0x40,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x33 '3' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x40,0x80,0x00,0x80,0x01,0x00,0x0E,0x00,0x01,0x00,0x00,0x80,0x00,0x80,0x00,0x80,0x41,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x34 '4' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x03,0x00,0x05,0x00,0x09,0x00,0x11,0x00,0x21,0x00,0x41,0x00,0x7F,0xC0,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x35 '5' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x80,0x20,0x00,0x20,0x00,0x20,0x00,0x3E,0x00,0x01,0x00,0x00,0x80,0x00,0x80,0x00,0x80,0x41,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x36 '6' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x10,0x00,0x20,0x00,0x40,0x00,0x5E,0x00,0x61,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x37 '7' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x04,0x00,0x04,0x00,0x08,0x00,0x08,0x00,0x10,0x00,0x10,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x38 '8' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x21,0x00,0x40,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x39 '9' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x20,0x80,0x1F,0x80,0x00,0x80,0x01,0x00,0x02,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x3A ':' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x00,0x00,0x00,0x00,0x10,0x10,0x00,0x00,0x00, 7, // 0x3B ';' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x20,0x20, 12, // 0x3C '<' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x03,0x00,0x0C,0x00,0x30,0x00,0x30,0x00,0x0C,0x00,0x03,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 12, // 0x3D '=' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xE0,0x00,0x00,0x00,0x00,0x3F,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 12, // 0x3E '>' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x0C,0x00,0x03,0x00,0x00,0xC0,0x00,0xC0,0x03,0x00,0x0C,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x3F '?' 0x00,0x00,0x00,0x00,0x3C,0x42,0x02,0x02,0x04,0x08,0x10,0x10,0x00,0x10,0x10,0x00,0x00,0x00, 15, // 0x40 '@' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x80,0x18,0x60,0x20,0x10,0x23,0xD0,0x44,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x44,0x48,0x23,0xF0,0x20,0x00,0x18,0x00,0x07,0xC0,0x00,0x00, 10, // 0x41 'A' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x21,0x00,0x21,0x00,0x40,0x80,0x7F,0x80,0x40,0x80,0x80,0x40,0x80,0x40,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x42 'B' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x7E,0x00,0x41,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x41,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x43 'C' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x30,0xC0,0x20,0x40,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x20,0x40,0x30,0xC0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x44 'D' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x41,0x80,0x40,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x41,0x80,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x45 'E' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x7F,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x46 'F' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x40,0x00,0x40,0x00,0x40,0x00,0x7F,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 12, // 0x47 'G' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x30,0x60,0x20,0x20,0x40,0x00,0x40,0x00,0x41,0xE0,0x40,0x20,0x40,0x20,0x20,0x20,0x30,0x20,0x0F,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x48 'H' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7F,0xC0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x49 'I' 0x00,0x00,0x00,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00,0x00, 7, // 0x4A 'J' 0x00,0x00,0x00,0x00,0x3C,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x08,0xF0,0x00,0x00,0x00, 10, // 0x4B 'K' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x41,0x00,0x42,0x00,0x44,0x00,0x48,0x00,0x50,0x00,0x68,0x00,0x44,0x00,0x42,0x00,0x41,0x00,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x4C 'L' 0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7F,0x00,0x00,0x00, 13, // 0x4D 'M' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x30,0x50,0x50,0x50,0x50,0x48,0x90,0x48,0x90,0x45,0x10,0x45,0x10,0x42,0x10,0x42,0x10,0x40,0x10,0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x4E 'N' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x60,0x40,0x50,0x40,0x48,0x40,0x48,0x40,0x44,0x40,0x42,0x40,0x42,0x40,0x41,0x40,0x40,0xC0,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00, 12, // 0x4F 'O' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x30,0xC0,0x20,0x40,0x40,0x20,0x40,0x20,0x40,0x20,0x40,0x20,0x40,0x20,0x20,0x40,0x30,0xC0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x50 'P' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x41,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x41,0x00,0x7E,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 12, // 0x51 'Q' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x30,0xC0,0x20,0x40,0x40,0x20,0x40,0x20,0x40,0x20,0x40,0x20,0x40,0x20,0x20,0x40,0x30,0xC0,0x0F,0x00,0x01,0x00,0x01,0x00,0x00,0xE0, 10, // 0x52 'R' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x42,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x42,0x00,0x7C,0x00,0x42,0x00,0x41,0x00,0x40,0x80,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x53 'S' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x20,0x80,0x40,0x00,0x40,0x00,0x20,0x00,0x1E,0x00,0x01,0x00,0x00,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x54 'T' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x80,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x55 'U' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x20,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x56 'V' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x80,0x40,0x40,0x80,0x40,0x80,0x40,0x80,0x21,0x00,0x21,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 15, // 0x57 'W' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x04,0x41,0x04,0x22,0x88,0x22,0x88,0x22,0x88,0x12,0x90,0x14,0x50,0x14,0x50,0x14,0x50,0x08,0x20,0x08,0x20,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x58 'X' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x21,0x00,0x21,0x00,0x12,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x12,0x00,0x21,0x00,0x21,0x00,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x59 'Y' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x41,0x00,0x22,0x00,0x22,0x00,0x14,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x5A 'Z' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x00,0x80,0x01,0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x08,0x00,0x10,0x00,0x20,0x00,0x40,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x5B '[' 0x00,0x00,0x00,0x3C,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3C, 7, // 0x5C '\' 0x00,0x00,0x00,0x80,0x40,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x04,0x02,0x00, 7, // 0x5D ']' 0x00,0x00,0x00,0x78,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x78, 12, // 0x5E '^' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x09,0x00,0x10,0x80,0x20,0x40,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 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,0x00,0x00,0x00,0x00,0x00,0xFF,0xC0,0x00,0x00, 10, // 0x60 '`' 0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x61 'a' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x01,0x00,0x3F,0x00,0x41,0x00,0x41,0x00,0x43,0x00,0x3D,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x62 'b' 0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x5C,0x00,0x62,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x42,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x63 'c' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x21,0x40,0x40,0x40,0x40,0x21,0x1E,0x00,0x00,0x00, 9, // 0x64 'd' 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x1F,0x00,0x21,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x23,0x00,0x1D,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x65 'e' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x22,0x00,0x41,0x00,0x7F,0x00,0x40,0x00,0x40,0x00,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x66 'f' 0x00,0x00,0x00,0x1C,0x20,0x20,0x20,0x7C,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00, 9, // 0x67 'g' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x21,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x23,0x00,0x1D,0x00,0x01,0x00,0x22,0x00,0x1C,0x00, 9, // 0x68 'h' 0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x5E,0x00,0x61,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 3, // 0x69 'i' 0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, 5, // 0x6A 'j' 0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xE0, 9, // 0x6B 'k' 0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x42,0x00,0x44,0x00,0x48,0x00,0x50,0x00,0x68,0x00,0x44,0x00,0x42,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 3, // 0x6C 'l' 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, 15, // 0x6D 'm' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2E,0x70,0x31,0x88,0x21,0x08,0x21,0x08,0x21,0x08,0x21,0x08,0x21,0x08,0x21,0x08,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x6E 'n' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5E,0x00,0x61,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x6F 'o' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x70 'p' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5C,0x00,0x62,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x42,0x00,0x7C,0x00,0x40,0x00,0x40,0x00,0x40,0x00, 9, // 0x71 'q' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x21,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x23,0x00,0x1D,0x00,0x01,0x00,0x01,0x00,0x01,0x00, 6, // 0x72 'r' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5C,0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, 8, // 0x73 's' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x40,0x30,0x0C,0x02,0x42,0x3C,0x00,0x00,0x00, 6, // 0x74 't' 0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x7C,0x20,0x20,0x20,0x20,0x20,0x20,0x1C,0x00,0x00,0x00, 9, // 0x75 'u' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x43,0x00,0x3D,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x76 'v' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x14,0x00,0x14,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 13, // 0x77 'w' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x10,0x42,0x10,0x25,0x20,0x25,0x20,0x28,0xA0,0x28,0xA0,0x10,0x40,0x10,0x40,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x78 'x' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x22,0x00,0x14,0x00,0x08,0x00,0x08,0x00,0x14,0x00,0x22,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x79 'y' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x14,0x00,0x14,0x00,0x08,0x00,0x08,0x00,0x10,0x00,0x10,0x00, 9, // 0x7A 'z' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x10,0x00,0x20,0x00,0x40,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x7B '{' 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x10,0x00,0x60,0x00,0x10,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x07,0x00, 7, // 0x7C '|' 0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, 10, // 0x7D '}' 0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x02,0x00,0x01,0x80,0x02,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x38,0x00, 12, // 0x7E '~' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x20,0x24,0x20,0x42,0x40,0x41,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 15, // 0x7F '' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xF8,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x3F,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, 0 }; const int8u verdana18_bold[] = { 18, 4, 32, 128-32, 0x00,0x00,0x13,0x00,0x26,0x00,0x4B,0x00,0x70,0x00,0x95,0x00,0xCC,0x00,0xF1,0x00,0x04,0x01, 0x17,0x01,0x2A,0x01,0x4F,0x01,0x74,0x01,0x87,0x01,0x9A,0x01,0xAD,0x01,0xD2,0x01,0xF7,0x01, 0x1C,0x02,0x41,0x02,0x66,0x02,0x8B,0x02,0xB0,0x02,0xD5,0x02,0xFA,0x02,0x1F,0x03,0x44,0x03, 0x57,0x03,0x6A,0x03,0x8F,0x03,0xB4,0x03,0xD9,0x03,0xFE,0x03,0x23,0x04,0x48,0x04,0x6D,0x04, 0x92,0x04,0xB7,0x04,0xDC,0x04,0x01,0x05,0x26,0x05,0x4B,0x05,0x5E,0x05,0x71,0x05,0x96,0x05, 0xBB,0x05,0xE0,0x05,0x05,0x06,0x2A,0x06,0x4F,0x06,0x74,0x06,0x99,0x06,0xBE,0x06,0xE3,0x06, 0x08,0x07,0x2D,0x07,0x52,0x07,0x77,0x07,0x9C,0x07,0xC1,0x07,0xD4,0x07,0xF9,0x07,0x0C,0x08, 0x31,0x08,0x56,0x08,0x7B,0x08,0xA0,0x08,0xC5,0x08,0xD8,0x08,0xFD,0x08,0x22,0x09,0x35,0x09, 0x5A,0x09,0x7F,0x09,0x92,0x09,0xA5,0x09,0xCA,0x09,0xDD,0x09,0x02,0x0A,0x27,0x0A,0x4C,0x0A, 0x71,0x0A,0x96,0x0A,0xA9,0x0A,0xCE,0x0A,0xE1,0x0A,0x06,0x0B,0x2B,0x0B,0x50,0x0B,0x75,0x0B, 0x9A,0x0B,0xBF,0x0B,0xE4,0x0B,0xF7,0x0B,0x1C,0x0C,0x41,0x0C, 5, // 0x20 ' ' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x21 '!' 0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x30,0x30,0x00,0x00,0x00, 9, // 0x22 '"' 0x00,0x00,0x00,0x00,0x00,0x00,0x36,0x00,0x36,0x00,0x36,0x00,0x36,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 13, // 0x23 '#' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x20,0x04,0x20,0x08,0x40,0x3F,0xF0,0x3F,0xF0,0x08,0x40,0x10,0x80,0x7F,0xE0,0x7F,0xE0,0x21,0x00,0x21,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x24 '$' 0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x1F,0x80,0x34,0xC0,0x64,0xC0,0x64,0x00,0x3C,0x00,0x07,0x80,0x04,0xC0,0x64,0xC0,0x65,0x80,0x3F,0x00,0x04,0x00,0x04,0x00,0x00,0x00, 19, // 0x25 '%' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x08,0x00,0x63,0x10,0x00,0x63,0x10,0x00,0x63,0x20,0x00,0x63,0x2F,0x80,0x63,0x58,0xC0,0x3E,0x98,0xC0,0x00,0x98,0xC0,0x01,0x18,0xC0,0x01,0x18,0xC0,0x02,0x0F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 13, // 0x26 '&' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x33,0x00,0x33,0x00,0x1E,0x60,0x36,0x60,0x63,0x60,0x61,0xC0,0x60,0xC0,0x30,0xE0,0x1F,0x30,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x27 ''' 0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x28 '(' 0x00,0x00,0x00,0x06,0x0C,0x18,0x30,0x30,0x60,0x60,0x60,0x60,0x60,0x30,0x30,0x18,0x0C,0x06, 8, // 0x29 ')' 0x00,0x00,0x00,0x60,0x30,0x18,0x0C,0x0C,0x06,0x06,0x06,0x06,0x06,0x0C,0x0C,0x18,0x30,0x60, 11, // 0x2A '*' 0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x24,0x80,0x15,0x00,0x0E,0x00,0x15,0x00,0x24,0x80,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 13, // 0x2B '+' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x3F,0xE0,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x2C ',' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x60,0x60,0x60,0xC0,0xC0, 7, // 0x2D '-' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 5, // 0x2E '.' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x00,0x00,0x00, 10, // 0x2F '/' 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x03,0x00,0x03,0x00,0x06,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x30,0x00,0x30,0x00,0x60,0x00,0x60,0x00,0x00,0x00, 11, // 0x30 '0' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x31,0x80,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x31,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x31 '1' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x1E,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x1F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x32 '2' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x61,0x80,0x60,0xC0,0x00,0xC0,0x01,0x80,0x03,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x7F,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x33 '3' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x61,0x80,0x60,0xC0,0x00,0xC0,0x01,0x80,0x0F,0x00,0x01,0x80,0x00,0xC0,0x60,0xC0,0x61,0x80,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x34 '4' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x03,0x80,0x05,0x80,0x09,0x80,0x11,0x80,0x21,0x80,0x41,0x80,0x7F,0xE0,0x01,0x80,0x01,0x80,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x35 '5' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xC0,0x30,0x00,0x30,0x00,0x30,0x00,0x3F,0x00,0x01,0x80,0x00,0xC0,0x00,0xC0,0x60,0xC0,0x61,0x80,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x36 '6' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x18,0x00,0x30,0x00,0x60,0x00,0x6F,0x00,0x71,0x80,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x31,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x37 '7' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xC0,0x00,0xC0,0x01,0x80,0x01,0x80,0x03,0x00,0x03,0x00,0x06,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x38 '8' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x31,0x80,0x60,0xC0,0x60,0xC0,0x31,0x80,0x1F,0x00,0x31,0x80,0x60,0xC0,0x60,0xC0,0x31,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x39 '9' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x31,0x80,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x31,0xC0,0x1E,0xC0,0x00,0xC0,0x01,0x80,0x03,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x3A ':' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x00,0x00,0x30,0x30,0x30,0x00,0x00,0x00, 6, // 0x3B ';' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x00,0x00,0x38,0x30,0x30,0x30,0x60,0x60, 13, // 0x3C '<' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0xC0,0x03,0x00,0x0C,0x00,0x30,0x00,0x30,0x00,0x0C,0x00,0x03,0x00,0x00,0xC0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00, 13, // 0x3D '=' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 13, // 0x3E '>' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x18,0x00,0x06,0x00,0x01,0x80,0x00,0x60,0x00,0x60,0x01,0x80,0x06,0x00,0x18,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, // 0x3F '?' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x03,0x00,0x03,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x00,0x00,0x18,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 14, // 0x40 '@' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x80,0x18,0x60,0x20,0x10,0x27,0xD0,0x4C,0xC8,0x4C,0xC8,0x4C,0xC8,0x4C,0xC8,0x4C,0xC8,0x27,0xF0,0x20,0x00,0x18,0x00,0x07,0xC0,0x00,0x00, 12, // 0x41 'A' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x06,0x00,0x0F,0x00,0x0F,0x00,0x19,0x80,0x19,0x80,0x30,0xC0,0x3F,0xC0,0x30,0xC0,0x60,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x42 'B' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x00,0x7F,0x00,0x61,0x80,0x60,0xC0,0x60,0xC0,0x61,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x43 'C' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x38,0xC0,0x30,0xC0,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x30,0xC0,0x38,0xC0,0x0F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 12, // 0x44 'D' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x61,0xC0,0x60,0xC0,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0xC0,0x61,0xC0,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x45 'E' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x46 'F' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 12, // 0x47 'G' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xC0,0x38,0x60,0x30,0x60,0x60,0x00,0x60,0x00,0x63,0xE0,0x60,0x60,0x60,0x60,0x30,0x60,0x38,0x60,0x0F,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, 12, // 0x48 'H' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x7F,0xE0,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x49 'I' 0x00,0x00,0x00,0x00,0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00,0x00, 8, // 0x4A 'J' 0x00,0x00,0x00,0x00,0x3E,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0C,0xF8,0x00,0x00,0x00, 12, // 0x4B 'K' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x60,0xC0,0x61,0x80,0x63,0x00,0x66,0x00,0x6C,0x00,0x7E,0x00,0x73,0x00,0x61,0x80,0x60,0xC0,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x4C 'L' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 14, // 0x4D 'M' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x38,0x70,0x38,0x70,0x78,0x58,0x58,0x58,0xD8,0x4C,0x98,0x4D,0x98,0x47,0x18,0x47,0x18,0x42,0x18,0x40,0x18,0x00,0x00,0x00,0x00,0x00,0x00, 12, // 0x4E 'N' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x20,0x70,0x20,0x58,0x20,0x4C,0x20,0x4C,0x20,0x46,0x20,0x43,0x20,0x43,0x20,0x41,0xA0,0x40,0xE0,0x40,0xE0,0x00,0x00,0x00,0x00,0x00,0x00, 13, // 0x4F 'O' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x38,0xE0,0x30,0x60,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x30,0x60,0x38,0xE0,0x0F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x50 'P' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x61,0x80,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x61,0x80,0x7F,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 13, // 0x51 'Q' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x38,0xE0,0x30,0x60,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x30,0x60,0x38,0xE0,0x0F,0x80,0x03,0x00,0x03,0x80,0x01,0xF0, 12, // 0x52 'R' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x61,0x80,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x61,0x80,0x7F,0x00,0x61,0x80,0x60,0xC0,0x60,0x60,0x60,0x30,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x53 'S' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x80,0x30,0xC0,0x60,0xC0,0x60,0x00,0x7C,0x00,0x3F,0x80,0x03,0xC0,0x00,0xC0,0x60,0xC0,0x61,0x80,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x54 'T' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 12, // 0x55 'U' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x30,0xC0,0x1F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x56 'V' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x31,0x80,0x31,0x80,0x31,0x80,0x1B,0x00,0x1B,0x00,0x1B,0x00,0x0E,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 16, // 0x57 'W' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x86,0x61,0x86,0x63,0xC6,0x33,0xCC,0x32,0x4C,0x32,0x4C,0x1E,0x78,0x1C,0x38,0x1C,0x38,0x0C,0x30,0x0C,0x30,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x58 'X' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xC0,0x31,0x80,0x31,0x80,0x1B,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x1B,0x00,0x31,0x80,0x31,0x80,0x60,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x59 'Y' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x1E,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x5A 'Z' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x01,0x80,0x03,0x00,0x06,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x30,0x00,0x60,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x5B '[' 0x00,0x00,0x00,0x3E,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3E, 10, // 0x5C '\' 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x30,0x00,0x30,0x00,0x18,0x00,0x18,0x00,0x0C,0x00,0x0C,0x00,0x06,0x00,0x06,0x00,0x03,0x00,0x03,0x00,0x01,0x80,0x01,0x80,0x00,0x00, 8, // 0x5D ']' 0x00,0x00,0x00,0x7C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x7C, 13, // 0x5E '^' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x0F,0x00,0x19,0x80,0x30,0xC0,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 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,0x00,0x00,0x00,0x00,0x00,0xFF,0xE0,0x00,0x00, 11, // 0x60 '`' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x61 'a' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x01,0x80,0x01,0x80,0x3F,0x80,0x61,0x80,0x61,0x80,0x63,0x80,0x3D,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x62 'b' 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x6E,0x00,0x73,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 8, // 0x63 'c' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x33,0x60,0x60,0x60,0x60,0x33,0x1E,0x00,0x00,0x00, 10, // 0x64 'd' 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x1F,0x80,0x31,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x80,0x1D,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x65 'e' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x7F,0x80,0x60,0x00,0x60,0x00,0x31,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 6, // 0x66 'f' 0x00,0x00,0x00,0x1C,0x30,0x30,0x30,0x7C,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x00, 10, // 0x67 'g' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x80,0x31,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x80,0x1D,0x80,0x01,0x80,0x03,0x00,0x3E,0x00, 10, // 0x68 'h' 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x6F,0x00,0x71,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 4, // 0x69 'i' 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00, 6, // 0x6A 'j' 0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF0, 10, // 0x6B 'k' 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x61,0x80,0x63,0x00,0x66,0x00,0x6C,0x00,0x7E,0x00,0x73,0x00,0x61,0x80,0x60,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, 4, // 0x6C 'l' 0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00, 16, // 0x6D 'm' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6F,0x3C,0x71,0xC6,0x61,0x86,0x61,0x86,0x61,0x86,0x61,0x86,0x61,0x86,0x61,0x86,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x6E 'n' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6F,0x00,0x71,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x6F 'o' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x70 'p' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6E,0x00,0x73,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x00,0x7E,0x00,0x60,0x00,0x60,0x00,0x60,0x00, 10, // 0x71 'q' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x80,0x31,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x80,0x1D,0x80,0x01,0x80,0x01,0x80,0x01,0x80, 7, // 0x72 'r' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6E,0x7E,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00, 9, // 0x73 's' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x61,0x00,0x60,0x00,0x7E,0x00,0x3F,0x00,0x03,0x00,0x43,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 7, // 0x74 't' 0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x7E,0x30,0x30,0x30,0x30,0x30,0x30,0x1E,0x00,0x00,0x00, 10, // 0x75 'u' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x80,0x3D,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x76 'v' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x33,0x00,0x33,0x00,0x33,0x00,0x1E,0x00,0x1E,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 14, // 0x77 'w' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x18,0x63,0x18,0x63,0x18,0x37,0xB0,0x34,0xB0,0x3C,0xF0,0x18,0x60,0x18,0x60,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x78 'x' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x33,0x00,0x33,0x00,0x1E,0x00,0x1E,0x00,0x33,0x00,0x33,0x00,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 10, // 0x79 'y' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x33,0x00,0x33,0x00,0x33,0x00,0x1E,0x00,0x1E,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00, 9, // 0x7A 'z' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x03,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x60,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 11, // 0x7B '{' 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x80,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x70,0x00,0x18,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x07,0x80, 8, // 0x7C '|' 0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, 11, // 0x7D '}' 0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x03,0x00,0x01,0xC0,0x03,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x3C,0x00, 13, // 0x7E '~' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x10,0x24,0x10,0x42,0x10,0x41,0x20,0x40,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 15, // 0x7F '' 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xF8,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x3F,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, 0 }; } aggdraw-1.3.14/agg2/src/agg_gsv_text.cpp000066400000000000000000001004501417726601400200200ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Class gsv_text // //---------------------------------------------------------------------------- #include #include #include "agg_gsv_text.h" namespace agg { int8u gsv_default_font[] = { 0x40,0x00,0x6c,0x0f,0x15,0x00,0x0e,0x00,0xf9,0xff, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x0d,0x0a,0x0d,0x0a,0x46,0x6f,0x6e,0x74,0x20,0x28, 0x63,0x29,0x20,0x4d,0x69,0x63,0x72,0x6f,0x50,0x72, 0x6f,0x66,0x20,0x32,0x37,0x20,0x53,0x65,0x70,0x74, 0x65,0x6d,0x62,0x2e,0x31,0x39,0x38,0x39,0x00,0x0d, 0x0a,0x0d,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x02,0x00,0x12,0x00,0x34,0x00,0x46,0x00,0x94,0x00, 0xd0,0x00,0x2e,0x01,0x3e,0x01,0x64,0x01,0x8a,0x01, 0x98,0x01,0xa2,0x01,0xb4,0x01,0xba,0x01,0xc6,0x01, 0xcc,0x01,0xf0,0x01,0xfa,0x01,0x18,0x02,0x38,0x02, 0x44,0x02,0x68,0x02,0x98,0x02,0xa2,0x02,0xde,0x02, 0x0e,0x03,0x24,0x03,0x40,0x03,0x48,0x03,0x52,0x03, 0x5a,0x03,0x82,0x03,0xec,0x03,0xfa,0x03,0x26,0x04, 0x4c,0x04,0x6a,0x04,0x7c,0x04,0x8a,0x04,0xb6,0x04, 0xc4,0x04,0xca,0x04,0xe0,0x04,0xee,0x04,0xf8,0x04, 0x0a,0x05,0x18,0x05,0x44,0x05,0x5e,0x05,0x8e,0x05, 0xac,0x05,0xd6,0x05,0xe0,0x05,0xf6,0x05,0x00,0x06, 0x12,0x06,0x1c,0x06,0x28,0x06,0x36,0x06,0x48,0x06, 0x4e,0x06,0x60,0x06,0x6e,0x06,0x74,0x06,0x84,0x06, 0xa6,0x06,0xc8,0x06,0xe6,0x06,0x08,0x07,0x2c,0x07, 0x3c,0x07,0x68,0x07,0x7c,0x07,0x8c,0x07,0xa2,0x07, 0xb0,0x07,0xb6,0x07,0xd8,0x07,0xec,0x07,0x10,0x08, 0x32,0x08,0x54,0x08,0x64,0x08,0x88,0x08,0x98,0x08, 0xac,0x08,0xb6,0x08,0xc8,0x08,0xd2,0x08,0xe4,0x08, 0xf2,0x08,0x3e,0x09,0x48,0x09,0x94,0x09,0xc2,0x09, 0xc4,0x09,0xd0,0x09,0xe2,0x09,0x04,0x0a,0x0e,0x0a, 0x26,0x0a,0x34,0x0a,0x4a,0x0a,0x66,0x0a,0x70,0x0a, 0x7e,0x0a,0x8e,0x0a,0x9a,0x0a,0xa6,0x0a,0xb4,0x0a, 0xd8,0x0a,0xe2,0x0a,0xf6,0x0a,0x18,0x0b,0x22,0x0b, 0x32,0x0b,0x56,0x0b,0x60,0x0b,0x6e,0x0b,0x7c,0x0b, 0x8a,0x0b,0x9c,0x0b,0x9e,0x0b,0xb2,0x0b,0xc2,0x0b, 0xd8,0x0b,0xf4,0x0b,0x08,0x0c,0x30,0x0c,0x56,0x0c, 0x72,0x0c,0x90,0x0c,0xb2,0x0c,0xce,0x0c,0xe2,0x0c, 0xfe,0x0c,0x10,0x0d,0x26,0x0d,0x36,0x0d,0x42,0x0d, 0x4e,0x0d,0x5c,0x0d,0x78,0x0d,0x8c,0x0d,0x8e,0x0d, 0x90,0x0d,0x92,0x0d,0x94,0x0d,0x96,0x0d,0x98,0x0d, 0x9a,0x0d,0x9c,0x0d,0x9e,0x0d,0xa0,0x0d,0xa2,0x0d, 0xa4,0x0d,0xa6,0x0d,0xa8,0x0d,0xaa,0x0d,0xac,0x0d, 0xae,0x0d,0xb0,0x0d,0xb2,0x0d,0xb4,0x0d,0xb6,0x0d, 0xb8,0x0d,0xba,0x0d,0xbc,0x0d,0xbe,0x0d,0xc0,0x0d, 0xc2,0x0d,0xc4,0x0d,0xc6,0x0d,0xc8,0x0d,0xca,0x0d, 0xcc,0x0d,0xce,0x0d,0xd0,0x0d,0xd2,0x0d,0xd4,0x0d, 0xd6,0x0d,0xd8,0x0d,0xda,0x0d,0xdc,0x0d,0xde,0x0d, 0xe0,0x0d,0xe2,0x0d,0xe4,0x0d,0xe6,0x0d,0xe8,0x0d, 0xea,0x0d,0xec,0x0d,0x0c,0x0e,0x26,0x0e,0x48,0x0e, 0x64,0x0e,0x88,0x0e,0x92,0x0e,0xa6,0x0e,0xb4,0x0e, 0xd0,0x0e,0xee,0x0e,0x02,0x0f,0x16,0x0f,0x26,0x0f, 0x3c,0x0f,0x58,0x0f,0x6c,0x0f,0x6c,0x0f,0x6c,0x0f, 0x6c,0x0f,0x6c,0x0f,0x6c,0x0f,0x6c,0x0f,0x6c,0x0f, 0x6c,0x0f,0x6c,0x0f,0x6c,0x0f,0x6c,0x0f,0x6c,0x0f, 0x6c,0x0f,0x6c,0x0f,0x6c,0x0f,0x6c,0x0f,0x10,0x80, 0x05,0x95,0x00,0x72,0x00,0xfb,0xff,0x7f,0x01,0x7f, 0x01,0x01,0xff,0x01,0x05,0xfe,0x05,0x95,0xff,0x7f, 0x00,0x7a,0x01,0x86,0xff,0x7a,0x01,0x87,0x01,0x7f, 0xfe,0x7a,0x0a,0x87,0xff,0x7f,0x00,0x7a,0x01,0x86, 0xff,0x7a,0x01,0x87,0x01,0x7f,0xfe,0x7a,0x05,0xf2, 0x0b,0x95,0xf9,0x64,0x0d,0x9c,0xf9,0x64,0xfa,0x91, 0x0e,0x00,0xf1,0xfa,0x0e,0x00,0x04,0xfc,0x08,0x99, 0x00,0x63,0x04,0x9d,0x00,0x63,0x04,0x96,0xff,0x7f, 0x01,0x7f,0x01,0x01,0x00,0x01,0xfe,0x02,0xfd,0x01, 0xfc,0x00,0xfd,0x7f,0xfe,0x7e,0x00,0x7e,0x01,0x7e, 0x01,0x7f,0x02,0x7f,0x06,0x7e,0x02,0x7f,0x02,0x7e, 0xf2,0x89,0x02,0x7e,0x02,0x7f,0x06,0x7e,0x02,0x7f, 0x01,0x7f,0x01,0x7e,0x00,0x7c,0xfe,0x7e,0xfd,0x7f, 0xfc,0x00,0xfd,0x01,0xfe,0x02,0x00,0x01,0x01,0x01, 0x01,0x7f,0xff,0x7f,0x10,0xfd,0x15,0x95,0xee,0x6b, 0x05,0x95,0x02,0x7e,0x00,0x7e,0xff,0x7e,0xfe,0x7f, 0xfe,0x00,0xfe,0x02,0x00,0x02,0x01,0x02,0x02,0x01, 0x02,0x00,0x02,0x7f,0x03,0x7f,0x03,0x00,0x03,0x01, 0x02,0x01,0xfc,0xf2,0xfe,0x7f,0xff,0x7e,0x00,0x7e, 0x02,0x7e,0x02,0x00,0x02,0x01,0x01,0x02,0x00,0x02, 0xfe,0x02,0xfe,0x00,0x07,0xf9,0x15,0x8d,0xff,0x7f, 0x01,0x7f,0x01,0x01,0x00,0x01,0xff,0x01,0xff,0x00, 0xff,0x7f,0xff,0x7e,0xfe,0x7b,0xfe,0x7d,0xfe,0x7e, 0xfe,0x7f,0xfd,0x00,0xfd,0x01,0xff,0x02,0x00,0x03, 0x01,0x02,0x06,0x04,0x02,0x02,0x01,0x02,0x00,0x02, 0xff,0x02,0xfe,0x01,0xfe,0x7f,0xff,0x7e,0x00,0x7e, 0x01,0x7d,0x02,0x7d,0x05,0x79,0x02,0x7e,0x03,0x7f, 0x01,0x00,0x01,0x01,0x00,0x01,0xf1,0xfe,0xfe,0x01, 0xff,0x02,0x00,0x03,0x01,0x02,0x02,0x02,0x00,0x86, 0x01,0x7e,0x08,0x75,0x02,0x7e,0x02,0x7f,0x05,0x80, 0x05,0x93,0xff,0x01,0x01,0x01,0x01,0x7f,0x00,0x7e, 0xff,0x7e,0xff,0x7f,0x06,0xf1,0x0b,0x99,0xfe,0x7e, 0xfe,0x7d,0xfe,0x7c,0xff,0x7b,0x00,0x7c,0x01,0x7b, 0x02,0x7c,0x02,0x7d,0x02,0x7e,0xfe,0x9e,0xfe,0x7c, 0xff,0x7d,0xff,0x7b,0x00,0x7c,0x01,0x7b,0x01,0x7d, 0x02,0x7c,0x05,0x85,0x03,0x99,0x02,0x7e,0x02,0x7d, 0x02,0x7c,0x01,0x7b,0x00,0x7c,0xff,0x7b,0xfe,0x7c, 0xfe,0x7d,0xfe,0x7e,0x02,0x9e,0x02,0x7c,0x01,0x7d, 0x01,0x7b,0x00,0x7c,0xff,0x7b,0xff,0x7d,0xfe,0x7c, 0x09,0x85,0x08,0x95,0x00,0x74,0xfb,0x89,0x0a,0x7a, 0x00,0x86,0xf6,0x7a,0x0d,0xf4,0x0d,0x92,0x00,0x6e, 0xf7,0x89,0x12,0x00,0x04,0xf7,0x06,0x81,0xff,0x7f, 0xff,0x01,0x01,0x01,0x01,0x7f,0x00,0x7e,0xff,0x7e, 0xff,0x7f,0x06,0x84,0x04,0x89,0x12,0x00,0x04,0xf7, 0x05,0x82,0xff,0x7f,0x01,0x7f,0x01,0x01,0xff,0x01, 0x05,0xfe,0x00,0xfd,0x0e,0x18,0x00,0xeb,0x09,0x95, 0xfd,0x7f,0xfe,0x7d,0xff,0x7b,0x00,0x7d,0x01,0x7b, 0x02,0x7d,0x03,0x7f,0x02,0x00,0x03,0x01,0x02,0x03, 0x01,0x05,0x00,0x03,0xff,0x05,0xfe,0x03,0xfd,0x01, 0xfe,0x00,0x0b,0xeb,0x06,0x91,0x02,0x01,0x03,0x03, 0x00,0x6b,0x09,0x80,0x04,0x90,0x00,0x01,0x01,0x02, 0x01,0x01,0x02,0x01,0x04,0x00,0x02,0x7f,0x01,0x7f, 0x01,0x7e,0x00,0x7e,0xff,0x7e,0xfe,0x7d,0xf6,0x76, 0x0e,0x00,0x03,0x80,0x05,0x95,0x0b,0x00,0xfa,0x78, 0x03,0x00,0x02,0x7f,0x01,0x7f,0x01,0x7d,0x00,0x7e, 0xff,0x7d,0xfe,0x7e,0xfd,0x7f,0xfd,0x00,0xfd,0x01, 0xff,0x01,0xff,0x02,0x11,0xfc,0x0d,0x95,0xf6,0x72, 0x0f,0x00,0xfb,0x8e,0x00,0x6b,0x07,0x80,0x0f,0x95, 0xf6,0x00,0xff,0x77,0x01,0x01,0x03,0x01,0x03,0x00, 0x03,0x7f,0x02,0x7e,0x01,0x7d,0x00,0x7e,0xff,0x7d, 0xfe,0x7e,0xfd,0x7f,0xfd,0x00,0xfd,0x01,0xff,0x01, 0xff,0x02,0x11,0xfc,0x10,0x92,0xff,0x02,0xfd,0x01, 0xfe,0x00,0xfd,0x7f,0xfe,0x7d,0xff,0x7b,0x00,0x7b, 0x01,0x7c,0x02,0x7e,0x03,0x7f,0x01,0x00,0x03,0x01, 0x02,0x02,0x01,0x03,0x00,0x01,0xff,0x03,0xfe,0x02, 0xfd,0x01,0xff,0x00,0xfd,0x7f,0xfe,0x7e,0xff,0x7d, 0x10,0xf9,0x11,0x95,0xf6,0x6b,0xfc,0x95,0x0e,0x00, 0x03,0xeb,0x08,0x95,0xfd,0x7f,0xff,0x7e,0x00,0x7e, 0x01,0x7e,0x02,0x7f,0x04,0x7f,0x03,0x7f,0x02,0x7e, 0x01,0x7e,0x00,0x7d,0xff,0x7e,0xff,0x7f,0xfd,0x7f, 0xfc,0x00,0xfd,0x01,0xff,0x01,0xff,0x02,0x00,0x03, 0x01,0x02,0x02,0x02,0x03,0x01,0x04,0x01,0x02,0x01, 0x01,0x02,0x00,0x02,0xff,0x02,0xfd,0x01,0xfc,0x00, 0x0c,0xeb,0x10,0x8e,0xff,0x7d,0xfe,0x7e,0xfd,0x7f, 0xff,0x00,0xfd,0x01,0xfe,0x02,0xff,0x03,0x00,0x01, 0x01,0x03,0x02,0x02,0x03,0x01,0x01,0x00,0x03,0x7f, 0x02,0x7e,0x01,0x7c,0x00,0x7b,0xff,0x7b,0xfe,0x7d, 0xfd,0x7f,0xfe,0x00,0xfd,0x01,0xff,0x02,0x10,0xfd, 0x05,0x8e,0xff,0x7f,0x01,0x7f,0x01,0x01,0xff,0x01, 0x00,0xf4,0xff,0x7f,0x01,0x7f,0x01,0x01,0xff,0x01, 0x05,0xfe,0x05,0x8e,0xff,0x7f,0x01,0x7f,0x01,0x01, 0xff,0x01,0x01,0xf3,0xff,0x7f,0xff,0x01,0x01,0x01, 0x01,0x7f,0x00,0x7e,0xff,0x7e,0xff,0x7f,0x06,0x84, 0x14,0x92,0xf0,0x77,0x10,0x77,0x04,0x80,0x04,0x8c, 0x12,0x00,0xee,0xfa,0x12,0x00,0x04,0xfa,0x04,0x92, 0x10,0x77,0xf0,0x77,0x14,0x80,0x03,0x90,0x00,0x01, 0x01,0x02,0x01,0x01,0x02,0x01,0x04,0x00,0x02,0x7f, 0x01,0x7f,0x01,0x7e,0x00,0x7e,0xff,0x7e,0xff,0x7f, 0xfc,0x7e,0x00,0x7d,0x00,0xfb,0xff,0x7f,0x01,0x7f, 0x01,0x01,0xff,0x01,0x09,0xfe,0x12,0x8d,0xff,0x02, 0xfe,0x01,0xfd,0x00,0xfe,0x7f,0xff,0x7f,0xff,0x7d, 0x00,0x7d,0x01,0x7e,0x02,0x7f,0x03,0x00,0x02,0x01, 0x01,0x02,0xfb,0x88,0xfe,0x7e,0xff,0x7d,0x00,0x7d, 0x01,0x7e,0x01,0x7f,0x07,0x8b,0xff,0x78,0x00,0x7e, 0x02,0x7f,0x02,0x00,0x02,0x02,0x01,0x03,0x00,0x02, 0xff,0x03,0xff,0x02,0xfe,0x02,0xfe,0x01,0xfd,0x01, 0xfd,0x00,0xfd,0x7f,0xfe,0x7f,0xfe,0x7e,0xff,0x7e, 0xff,0x7d,0x00,0x7d,0x01,0x7d,0x01,0x7e,0x02,0x7e, 0x02,0x7f,0x03,0x7f,0x03,0x00,0x03,0x01,0x02,0x01, 0x01,0x01,0xfe,0x8d,0xff,0x78,0x00,0x7e,0x01,0x7f, 0x08,0xfb,0x09,0x95,0xf8,0x6b,0x08,0x95,0x08,0x6b, 0xf3,0x87,0x0a,0x00,0x04,0xf9,0x04,0x95,0x00,0x6b, 0x00,0x95,0x09,0x00,0x03,0x7f,0x01,0x7f,0x01,0x7e, 0x00,0x7e,0xff,0x7e,0xff,0x7f,0xfd,0x7f,0xf7,0x80, 0x09,0x00,0x03,0x7f,0x01,0x7f,0x01,0x7e,0x00,0x7d, 0xff,0x7e,0xff,0x7f,0xfd,0x7f,0xf7,0x00,0x11,0x80, 0x12,0x90,0xff,0x02,0xfe,0x02,0xfe,0x01,0xfc,0x00, 0xfe,0x7f,0xfe,0x7e,0xff,0x7e,0xff,0x7d,0x00,0x7b, 0x01,0x7d,0x01,0x7e,0x02,0x7e,0x02,0x7f,0x04,0x00, 0x02,0x01,0x02,0x02,0x01,0x02,0x03,0xfb,0x04,0x95, 0x00,0x6b,0x00,0x95,0x07,0x00,0x03,0x7f,0x02,0x7e, 0x01,0x7e,0x01,0x7d,0x00,0x7b,0xff,0x7d,0xff,0x7e, 0xfe,0x7e,0xfd,0x7f,0xf9,0x00,0x11,0x80,0x04,0x95, 0x00,0x6b,0x00,0x95,0x0d,0x00,0xf3,0xf6,0x08,0x00, 0xf8,0xf5,0x0d,0x00,0x02,0x80,0x04,0x95,0x00,0x6b, 0x00,0x95,0x0d,0x00,0xf3,0xf6,0x08,0x00,0x06,0xf5, 0x12,0x90,0xff,0x02,0xfe,0x02,0xfe,0x01,0xfc,0x00, 0xfe,0x7f,0xfe,0x7e,0xff,0x7e,0xff,0x7d,0x00,0x7b, 0x01,0x7d,0x01,0x7e,0x02,0x7e,0x02,0x7f,0x04,0x00, 0x02,0x01,0x02,0x02,0x01,0x02,0x00,0x03,0xfb,0x80, 0x05,0x00,0x03,0xf8,0x04,0x95,0x00,0x6b,0x0e,0x95, 0x00,0x6b,0xf2,0x8b,0x0e,0x00,0x04,0xf5,0x04,0x95, 0x00,0x6b,0x04,0x80,0x0c,0x95,0x00,0x70,0xff,0x7d, 0xff,0x7f,0xfe,0x7f,0xfe,0x00,0xfe,0x01,0xff,0x01, 0xff,0x03,0x00,0x02,0x0e,0xf9,0x04,0x95,0x00,0x6b, 0x0e,0x95,0xf2,0x72,0x05,0x85,0x09,0x74,0x03,0x80, 0x04,0x95,0x00,0x6b,0x00,0x80,0x0c,0x00,0x01,0x80, 0x04,0x95,0x00,0x6b,0x00,0x95,0x08,0x6b,0x08,0x95, 0xf8,0x6b,0x08,0x95,0x00,0x6b,0x04,0x80,0x04,0x95, 0x00,0x6b,0x00,0x95,0x0e,0x6b,0x00,0x95,0x00,0x6b, 0x04,0x80,0x09,0x95,0xfe,0x7f,0xfe,0x7e,0xff,0x7e, 0xff,0x7d,0x00,0x7b,0x01,0x7d,0x01,0x7e,0x02,0x7e, 0x02,0x7f,0x04,0x00,0x02,0x01,0x02,0x02,0x01,0x02, 0x01,0x03,0x00,0x05,0xff,0x03,0xff,0x02,0xfe,0x02, 0xfe,0x01,0xfc,0x00,0x0d,0xeb,0x04,0x95,0x00,0x6b, 0x00,0x95,0x09,0x00,0x03,0x7f,0x01,0x7f,0x01,0x7e, 0x00,0x7d,0xff,0x7e,0xff,0x7f,0xfd,0x7f,0xf7,0x00, 0x11,0xf6,0x09,0x95,0xfe,0x7f,0xfe,0x7e,0xff,0x7e, 0xff,0x7d,0x00,0x7b,0x01,0x7d,0x01,0x7e,0x02,0x7e, 0x02,0x7f,0x04,0x00,0x02,0x01,0x02,0x02,0x01,0x02, 0x01,0x03,0x00,0x05,0xff,0x03,0xff,0x02,0xfe,0x02, 0xfe,0x01,0xfc,0x00,0x03,0xef,0x06,0x7a,0x04,0x82, 0x04,0x95,0x00,0x6b,0x00,0x95,0x09,0x00,0x03,0x7f, 0x01,0x7f,0x01,0x7e,0x00,0x7e,0xff,0x7e,0xff,0x7f, 0xfd,0x7f,0xf7,0x00,0x07,0x80,0x07,0x75,0x03,0x80, 0x11,0x92,0xfe,0x02,0xfd,0x01,0xfc,0x00,0xfd,0x7f, 0xfe,0x7e,0x00,0x7e,0x01,0x7e,0x01,0x7f,0x02,0x7f, 0x06,0x7e,0x02,0x7f,0x01,0x7f,0x01,0x7e,0x00,0x7d, 0xfe,0x7e,0xfd,0x7f,0xfc,0x00,0xfd,0x01,0xfe,0x02, 0x11,0xfd,0x08,0x95,0x00,0x6b,0xf9,0x95,0x0e,0x00, 0x01,0xeb,0x04,0x95,0x00,0x71,0x01,0x7d,0x02,0x7e, 0x03,0x7f,0x02,0x00,0x03,0x01,0x02,0x02,0x01,0x03, 0x00,0x0f,0x04,0xeb,0x01,0x95,0x08,0x6b,0x08,0x95, 0xf8,0x6b,0x09,0x80,0x02,0x95,0x05,0x6b,0x05,0x95, 0xfb,0x6b,0x05,0x95,0x05,0x6b,0x05,0x95,0xfb,0x6b, 0x07,0x80,0x03,0x95,0x0e,0x6b,0x00,0x95,0xf2,0x6b, 0x11,0x80,0x01,0x95,0x08,0x76,0x00,0x75,0x08,0x95, 0xf8,0x76,0x09,0xf5,0x11,0x95,0xf2,0x6b,0x00,0x95, 0x0e,0x00,0xf2,0xeb,0x0e,0x00,0x03,0x80,0x03,0x93, 0x00,0x6c,0x01,0x94,0x00,0x6c,0xff,0x94,0x05,0x00, 0xfb,0xec,0x05,0x00,0x02,0x81,0x00,0x95,0x0e,0x68, 0x00,0x83,0x06,0x93,0x00,0x6c,0x01,0x94,0x00,0x6c, 0xfb,0x94,0x05,0x00,0xfb,0xec,0x05,0x00,0x03,0x81, 0x03,0x87,0x08,0x05,0x08,0x7b,0xf0,0x80,0x08,0x04, 0x08,0x7c,0x03,0xf9,0x01,0x80,0x10,0x00,0x01,0x80, 0x06,0x95,0xff,0x7f,0xff,0x7e,0x00,0x7e,0x01,0x7f, 0x01,0x01,0xff,0x01,0x05,0xef,0x0f,0x8e,0x00,0x72, 0x00,0x8b,0xfe,0x02,0xfe,0x01,0xfd,0x00,0xfe,0x7f, 0xfe,0x7e,0xff,0x7d,0x00,0x7e,0x01,0x7d,0x02,0x7e, 0x02,0x7f,0x03,0x00,0x02,0x01,0x02,0x02,0x04,0xfd, 0x04,0x95,0x00,0x6b,0x00,0x8b,0x02,0x02,0x02,0x01, 0x03,0x00,0x02,0x7f,0x02,0x7e,0x01,0x7d,0x00,0x7e, 0xff,0x7d,0xfe,0x7e,0xfe,0x7f,0xfd,0x00,0xfe,0x01, 0xfe,0x02,0x0f,0xfd,0x0f,0x8b,0xfe,0x02,0xfe,0x01, 0xfd,0x00,0xfe,0x7f,0xfe,0x7e,0xff,0x7d,0x00,0x7e, 0x01,0x7d,0x02,0x7e,0x02,0x7f,0x03,0x00,0x02,0x01, 0x02,0x02,0x03,0xfd,0x0f,0x95,0x00,0x6b,0x00,0x8b, 0xfe,0x02,0xfe,0x01,0xfd,0x00,0xfe,0x7f,0xfe,0x7e, 0xff,0x7d,0x00,0x7e,0x01,0x7d,0x02,0x7e,0x02,0x7f, 0x03,0x00,0x02,0x01,0x02,0x02,0x04,0xfd,0x03,0x88, 0x0c,0x00,0x00,0x02,0xff,0x02,0xff,0x01,0xfe,0x01, 0xfd,0x00,0xfe,0x7f,0xfe,0x7e,0xff,0x7d,0x00,0x7e, 0x01,0x7d,0x02,0x7e,0x02,0x7f,0x03,0x00,0x02,0x01, 0x02,0x02,0x03,0xfd,0x0a,0x95,0xfe,0x00,0xfe,0x7f, 0xff,0x7d,0x00,0x6f,0xfd,0x8e,0x07,0x00,0x03,0xf2, 0x0f,0x8e,0x00,0x70,0xff,0x7d,0xff,0x7f,0xfe,0x7f, 0xfd,0x00,0xfe,0x01,0x09,0x91,0xfe,0x02,0xfe,0x01, 0xfd,0x00,0xfe,0x7f,0xfe,0x7e,0xff,0x7d,0x00,0x7e, 0x01,0x7d,0x02,0x7e,0x02,0x7f,0x03,0x00,0x02,0x01, 0x02,0x02,0x04,0xfd,0x04,0x95,0x00,0x6b,0x00,0x8a, 0x03,0x03,0x02,0x01,0x03,0x00,0x02,0x7f,0x01,0x7d, 0x00,0x76,0x04,0x80,0x03,0x95,0x01,0x7f,0x01,0x01, 0xff,0x01,0xff,0x7f,0x01,0xf9,0x00,0x72,0x04,0x80, 0x05,0x95,0x01,0x7f,0x01,0x01,0xff,0x01,0xff,0x7f, 0x01,0xf9,0x00,0x6f,0xff,0x7d,0xfe,0x7f,0xfe,0x00, 0x09,0x87,0x04,0x95,0x00,0x6b,0x0a,0x8e,0xf6,0x76, 0x04,0x84,0x07,0x78,0x02,0x80,0x04,0x95,0x00,0x6b, 0x04,0x80,0x04,0x8e,0x00,0x72,0x00,0x8a,0x03,0x03, 0x02,0x01,0x03,0x00,0x02,0x7f,0x01,0x7d,0x00,0x76, 0x00,0x8a,0x03,0x03,0x02,0x01,0x03,0x00,0x02,0x7f, 0x01,0x7d,0x00,0x76,0x04,0x80,0x04,0x8e,0x00,0x72, 0x00,0x8a,0x03,0x03,0x02,0x01,0x03,0x00,0x02,0x7f, 0x01,0x7d,0x00,0x76,0x04,0x80,0x08,0x8e,0xfe,0x7f, 0xfe,0x7e,0xff,0x7d,0x00,0x7e,0x01,0x7d,0x02,0x7e, 0x02,0x7f,0x03,0x00,0x02,0x01,0x02,0x02,0x01,0x03, 0x00,0x02,0xff,0x03,0xfe,0x02,0xfe,0x01,0xfd,0x00, 0x0b,0xf2,0x04,0x8e,0x00,0x6b,0x00,0x92,0x02,0x02, 0x02,0x01,0x03,0x00,0x02,0x7f,0x02,0x7e,0x01,0x7d, 0x00,0x7e,0xff,0x7d,0xfe,0x7e,0xfe,0x7f,0xfd,0x00, 0xfe,0x01,0xfe,0x02,0x0f,0xfd,0x0f,0x8e,0x00,0x6b, 0x00,0x92,0xfe,0x02,0xfe,0x01,0xfd,0x00,0xfe,0x7f, 0xfe,0x7e,0xff,0x7d,0x00,0x7e,0x01,0x7d,0x02,0x7e, 0x02,0x7f,0x03,0x00,0x02,0x01,0x02,0x02,0x04,0xfd, 0x04,0x8e,0x00,0x72,0x00,0x88,0x01,0x03,0x02,0x02, 0x02,0x01,0x03,0x00,0x01,0xf2,0x0e,0x8b,0xff,0x02, 0xfd,0x01,0xfd,0x00,0xfd,0x7f,0xff,0x7e,0x01,0x7e, 0x02,0x7f,0x05,0x7f,0x02,0x7f,0x01,0x7e,0x00,0x7f, 0xff,0x7e,0xfd,0x7f,0xfd,0x00,0xfd,0x01,0xff,0x02, 0x0e,0xfd,0x05,0x95,0x00,0x6f,0x01,0x7d,0x02,0x7f, 0x02,0x00,0xf8,0x8e,0x07,0x00,0x03,0xf2,0x04,0x8e, 0x00,0x76,0x01,0x7d,0x02,0x7f,0x03,0x00,0x02,0x01, 0x03,0x03,0x00,0x8a,0x00,0x72,0x04,0x80,0x02,0x8e, 0x06,0x72,0x06,0x8e,0xfa,0x72,0x08,0x80,0x03,0x8e, 0x04,0x72,0x04,0x8e,0xfc,0x72,0x04,0x8e,0x04,0x72, 0x04,0x8e,0xfc,0x72,0x07,0x80,0x03,0x8e,0x0b,0x72, 0x00,0x8e,0xf5,0x72,0x0e,0x80,0x02,0x8e,0x06,0x72, 0x06,0x8e,0xfa,0x72,0xfe,0x7c,0xfe,0x7e,0xfe,0x7f, 0xff,0x00,0x0f,0x87,0x0e,0x8e,0xf5,0x72,0x00,0x8e, 0x0b,0x00,0xf5,0xf2,0x0b,0x00,0x03,0x80,0x09,0x99, 0xfe,0x7f,0xff,0x7f,0xff,0x7e,0x00,0x7e,0x01,0x7e, 0x01,0x7f,0x01,0x7e,0x00,0x7e,0xfe,0x7e,0x01,0x8e, 0xff,0x7e,0x00,0x7e,0x01,0x7e,0x01,0x7f,0x01,0x7e, 0x00,0x7e,0xff,0x7e,0xfc,0x7e,0x04,0x7e,0x01,0x7e, 0x00,0x7e,0xff,0x7e,0xff,0x7f,0xff,0x7e,0x00,0x7e, 0x01,0x7e,0xff,0x8e,0x02,0x7e,0x00,0x7e,0xff,0x7e, 0xff,0x7f,0xff,0x7e,0x00,0x7e,0x01,0x7e,0x01,0x7f, 0x02,0x7f,0x05,0x87,0x04,0x95,0x00,0x77,0x00,0xfd, 0x00,0x77,0x04,0x80,0x05,0x99,0x02,0x7f,0x01,0x7f, 0x01,0x7e,0x00,0x7e,0xff,0x7e,0xff,0x7f,0xff,0x7e, 0x00,0x7e,0x02,0x7e,0xff,0x8e,0x01,0x7e,0x00,0x7e, 0xff,0x7e,0xff,0x7f,0xff,0x7e,0x00,0x7e,0x01,0x7e, 0x04,0x7e,0xfc,0x7e,0xff,0x7e,0x00,0x7e,0x01,0x7e, 0x01,0x7f,0x01,0x7e,0x00,0x7e,0xff,0x7e,0x01,0x8e, 0xfe,0x7e,0x00,0x7e,0x01,0x7e,0x01,0x7f,0x01,0x7e, 0x00,0x7e,0xff,0x7e,0xff,0x7f,0xfe,0x7f,0x09,0x87, 0x03,0x86,0x00,0x02,0x01,0x03,0x02,0x01,0x02,0x00, 0x02,0x7f,0x04,0x7d,0x02,0x7f,0x02,0x00,0x02,0x01, 0x01,0x02,0xee,0xfe,0x01,0x02,0x02,0x01,0x02,0x00, 0x02,0x7f,0x04,0x7d,0x02,0x7f,0x02,0x00,0x02,0x01, 0x01,0x03,0x00,0x02,0x03,0xf4,0x10,0x80,0x03,0x80, 0x07,0x15,0x08,0x6b,0xfe,0x85,0xf5,0x00,0x10,0xfb, 0x0d,0x95,0xf6,0x00,0x00,0x6b,0x0a,0x00,0x02,0x02, 0x00,0x08,0xfe,0x02,0xf6,0x00,0x0e,0xf4,0x03,0x80, 0x00,0x15,0x0a,0x00,0x02,0x7e,0x00,0x7e,0x00,0x7d, 0x00,0x7e,0xfe,0x7f,0xf6,0x00,0x0a,0x80,0x02,0x7e, 0x01,0x7e,0x00,0x7d,0xff,0x7d,0xfe,0x7f,0xf6,0x00, 0x10,0x80,0x03,0x80,0x00,0x15,0x0c,0x00,0xff,0x7e, 0x03,0xed,0x03,0xfd,0x00,0x03,0x02,0x00,0x00,0x12, 0x02,0x03,0x0a,0x00,0x00,0x6b,0x02,0x00,0x00,0x7d, 0xfe,0x83,0xf4,0x00,0x11,0x80,0x0f,0x80,0xf4,0x00, 0x00,0x15,0x0c,0x00,0xff,0xf6,0xf5,0x00,0x0f,0xf5, 0x04,0x95,0x07,0x76,0x00,0x0a,0x07,0x80,0xf9,0x76, 0x00,0x75,0xf8,0x80,0x07,0x0c,0x09,0xf4,0xf9,0x0c, 0x09,0xf4,0x03,0x92,0x02,0x03,0x07,0x00,0x03,0x7d, 0x00,0x7b,0xfc,0x7e,0x04,0x7d,0x00,0x7a,0xfd,0x7e, 0xf9,0x00,0xfe,0x02,0x06,0x89,0x02,0x00,0x06,0xf5, 0x03,0x95,0x00,0x6b,0x0c,0x15,0x00,0x6b,0x02,0x80, 0x03,0x95,0x00,0x6b,0x0c,0x15,0x00,0x6b,0xf8,0x96, 0x03,0x00,0x07,0xea,0x03,0x80,0x00,0x15,0x0c,0x80, 0xf7,0x76,0xfd,0x00,0x03,0x80,0x0a,0x75,0x03,0x80, 0x03,0x80,0x07,0x13,0x02,0x02,0x03,0x00,0x00,0x6b, 0x02,0x80,0x03,0x80,0x00,0x15,0x09,0x6b,0x09,0x15, 0x00,0x6b,0x03,0x80,0x03,0x80,0x00,0x15,0x00,0xf6, 0x0d,0x00,0x00,0x8a,0x00,0x6b,0x03,0x80,0x07,0x80, 0xfd,0x00,0xff,0x03,0x00,0x04,0x00,0x07,0x00,0x04, 0x01,0x02,0x03,0x01,0x06,0x00,0x03,0x7f,0x01,0x7e, 0x01,0x7c,0x00,0x79,0xff,0x7c,0xff,0x7d,0xfd,0x00, 0xfa,0x00,0x0e,0x80,0x03,0x80,0x00,0x15,0x0c,0x00, 0x00,0x6b,0x02,0x80,0x03,0x80,0x00,0x15,0x0a,0x00, 0x02,0x7f,0x01,0x7d,0x00,0x7b,0xff,0x7e,0xfe,0x7f, 0xf6,0x00,0x10,0xf7,0x11,0x8f,0xff,0x03,0xff,0x02, 0xfe,0x01,0xfa,0x00,0xfd,0x7f,0xff,0x7e,0x00,0x7c, 0x00,0x79,0x00,0x7b,0x01,0x7e,0x03,0x00,0x06,0x00, 0x02,0x00,0x01,0x03,0x01,0x02,0x03,0xfb,0x03,0x95, 0x0c,0x00,0xfa,0x80,0x00,0x6b,0x09,0x80,0x03,0x95, 0x00,0x77,0x06,0x7a,0x06,0x06,0x00,0x09,0xfa,0xf1, 0xfa,0x7a,0x0e,0x80,0x03,0x87,0x00,0x0b,0x02,0x02, 0x03,0x00,0x02,0x7e,0x01,0x02,0x04,0x00,0x02,0x7e, 0x00,0x75,0xfe,0x7e,0xfc,0x00,0xff,0x01,0xfe,0x7f, 0xfd,0x00,0xfe,0x02,0x07,0x8e,0x00,0x6b,0x09,0x80, 0x03,0x80,0x0e,0x15,0xf2,0x80,0x0e,0x6b,0x03,0x80, 0x03,0x95,0x00,0x6b,0x0e,0x00,0x00,0x7d,0xfe,0x98, 0x00,0x6b,0x05,0x80,0x03,0x95,0x00,0x75,0x02,0x7d, 0x0a,0x00,0x00,0x8e,0x00,0x6b,0x02,0x80,0x03,0x95, 0x00,0x6b,0x10,0x00,0x00,0x15,0xf8,0x80,0x00,0x6b, 0x0a,0x80,0x03,0x95,0x00,0x6b,0x10,0x00,0x00,0x15, 0xf8,0x80,0x00,0x6b,0x0a,0x00,0x00,0x7d,0x02,0x83, 0x10,0x80,0x03,0x95,0x00,0x6b,0x09,0x00,0x03,0x02, 0x00,0x08,0xfd,0x02,0xf7,0x00,0x0e,0x89,0x00,0x6b, 0x03,0x80,0x03,0x95,0x00,0x6b,0x09,0x00,0x03,0x02, 0x00,0x08,0xfd,0x02,0xf7,0x00,0x0e,0xf4,0x03,0x92, 0x02,0x03,0x07,0x00,0x03,0x7d,0x00,0x70,0xfd,0x7e, 0xf9,0x00,0xfe,0x02,0x03,0x89,0x09,0x00,0x02,0xf5, 0x03,0x80,0x00,0x15,0x00,0xf5,0x07,0x00,0x00,0x08, 0x02,0x03,0x06,0x00,0x02,0x7d,0x00,0x70,0xfe,0x7e, 0xfa,0x00,0xfe,0x02,0x00,0x08,0x0c,0xf6,0x0f,0x80, 0x00,0x15,0xf6,0x00,0xfe,0x7d,0x00,0x79,0x02,0x7e, 0x0a,0x00,0xf4,0xf7,0x07,0x09,0x07,0xf7,0x03,0x8c, 0x01,0x02,0x01,0x01,0x05,0x00,0x02,0x7f,0x01,0x7e, 0x00,0x74,0x00,0x86,0xff,0x01,0xfe,0x01,0xfb,0x00, 0xff,0x7f,0xff,0x7f,0x00,0x7c,0x01,0x7e,0x01,0x00, 0x05,0x00,0x02,0x00,0x01,0x02,0x03,0xfe,0x04,0x8e, 0x02,0x01,0x04,0x00,0x02,0x7f,0x01,0x7e,0x00,0x77, 0xff,0x7e,0xfe,0x7f,0xfc,0x00,0xfe,0x01,0xff,0x02, 0x00,0x09,0x01,0x02,0x02,0x02,0x03,0x01,0x02,0x01, 0x01,0x01,0x01,0x02,0x02,0xeb,0x03,0x80,0x00,0x15, 0x03,0x00,0x02,0x7e,0x00,0x7b,0xfe,0x7e,0xfd,0x00, 0x03,0x80,0x04,0x00,0x03,0x7e,0x00,0x78,0xfd,0x7e, 0xf9,0x00,0x0c,0x80,0x03,0x8c,0x02,0x02,0x02,0x01, 0x03,0x00,0x02,0x7f,0x01,0x7d,0xfe,0x7e,0xf9,0x7d, 0xff,0x7e,0x00,0x7d,0x03,0x7f,0x02,0x00,0x03,0x01, 0x02,0x01,0x02,0xfe,0x0d,0x8c,0xff,0x02,0xfe,0x01, 0xfc,0x00,0xfe,0x7f,0xff,0x7e,0x00,0x77,0x01,0x7e, 0x02,0x7f,0x04,0x00,0x02,0x01,0x01,0x02,0x00,0x0f, 0xff,0x02,0xfe,0x01,0xf9,0x00,0x0c,0xeb,0x03,0x88, 0x0a,0x00,0x00,0x02,0x00,0x03,0xfe,0x02,0xfa,0x00, 0xff,0x7e,0xff,0x7d,0x00,0x7b,0x01,0x7c,0x01,0x7f, 0x06,0x00,0x02,0x02,0x03,0xfe,0x03,0x8f,0x06,0x77, 0x06,0x09,0xfa,0x80,0x00,0x71,0xff,0x87,0xfb,0x79, 0x07,0x87,0x05,0x79,0x02,0x80,0x03,0x8d,0x02,0x02, 0x06,0x00,0x02,0x7e,0x00,0x7d,0xfc,0x7d,0x04,0x7e, 0x00,0x7d,0xfe,0x7e,0xfa,0x00,0xfe,0x02,0x04,0x85, 0x02,0x00,0x06,0xf9,0x03,0x8f,0x00,0x73,0x01,0x7e, 0x07,0x00,0x02,0x02,0x00,0x0d,0x00,0xf3,0x01,0x7e, 0x03,0x80,0x03,0x8f,0x00,0x73,0x01,0x7e,0x07,0x00, 0x02,0x02,0x00,0x0d,0x00,0xf3,0x01,0x7e,0xf8,0x90, 0x03,0x00,0x08,0xf0,0x03,0x80,0x00,0x15,0x00,0xf3, 0x02,0x00,0x06,0x07,0xfa,0xf9,0x07,0x78,0x03,0x80, 0x03,0x80,0x04,0x0c,0x02,0x03,0x04,0x00,0x00,0x71, 0x02,0x80,0x03,0x80,0x00,0x0f,0x06,0x77,0x06,0x09, 0x00,0x71,0x02,0x80,0x03,0x80,0x00,0x0f,0x0a,0xf1, 0x00,0x0f,0xf6,0xf8,0x0a,0x00,0x02,0xf9,0x05,0x80, 0xff,0x01,0xff,0x04,0x00,0x05,0x01,0x03,0x01,0x02, 0x06,0x00,0x02,0x7e,0x00,0x7d,0x00,0x7b,0x00,0x7c, 0xfe,0x7f,0xfa,0x00,0x0b,0x80,0x03,0x80,0x00,0x0f, 0x00,0xfb,0x01,0x03,0x01,0x02,0x05,0x00,0x02,0x7e, 0x01,0x7d,0x00,0x76,0x03,0x80,0x10,0x80,0x10,0x80, 0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80, 0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80, 0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80, 0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80, 0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80, 0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80, 0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80, 0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80, 0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80, 0x10,0x80,0x0a,0x8f,0x02,0x7f,0x01,0x7e,0x00,0x76, 0xff,0x7f,0xfe,0x7f,0xfb,0x00,0xff,0x01,0xff,0x01, 0x00,0x0a,0x01,0x02,0x01,0x01,0x05,0x00,0xf9,0x80, 0x00,0x6b,0x0c,0x86,0x0d,0x8a,0xff,0x03,0xfe,0x02, 0xfb,0x00,0xff,0x7e,0xff,0x7d,0x00,0x7b,0x01,0x7c, 0x01,0x7f,0x05,0x00,0x02,0x01,0x01,0x03,0x03,0xfc, 0x03,0x80,0x00,0x0f,0x00,0xfb,0x01,0x03,0x01,0x02, 0x04,0x00,0x01,0x7e,0x01,0x7d,0x00,0x76,0x00,0x8a, 0x01,0x03,0x02,0x02,0x03,0x00,0x02,0x7e,0x01,0x7d, 0x00,0x76,0x03,0x80,0x03,0x8f,0x00,0x74,0x01,0x7e, 0x02,0x7f,0x04,0x00,0x02,0x01,0x01,0x01,0x00,0x8d, 0x00,0x6e,0xff,0x7e,0xfe,0x7f,0xfb,0x00,0xfe,0x01, 0x0c,0x85,0x03,0x8d,0x01,0x02,0x03,0x00,0x02,0x7e, 0x01,0x02,0x03,0x00,0x02,0x7e,0x00,0x74,0xfe,0x7f, 0xfd,0x00,0xff,0x01,0xfe,0x7f,0xfd,0x00,0xff,0x01, 0x00,0x0c,0x06,0x82,0x00,0x6b,0x08,0x86,0x03,0x80, 0x0a,0x0f,0xf6,0x80,0x0a,0x71,0x03,0x80,0x03,0x8f, 0x00,0x73,0x01,0x7e,0x07,0x00,0x02,0x02,0x00,0x0d, 0x00,0xf3,0x01,0x7e,0x00,0x7e,0x03,0x82,0x03,0x8f, 0x00,0x79,0x02,0x7e,0x08,0x00,0x00,0x89,0x00,0x71, 0x02,0x80,0x03,0x8f,0x00,0x73,0x01,0x7e,0x03,0x00, 0x02,0x02,0x00,0x0d,0x00,0xf3,0x01,0x7e,0x03,0x00, 0x02,0x02,0x00,0x0d,0x00,0xf3,0x01,0x7e,0x03,0x80, 0x03,0x8f,0x00,0x73,0x01,0x7e,0x03,0x00,0x02,0x02, 0x00,0x0d,0x00,0xf3,0x01,0x7e,0x03,0x00,0x02,0x02, 0x00,0x0d,0x00,0xf3,0x01,0x7e,0x00,0x7e,0x03,0x82, 0x03,0x8d,0x00,0x02,0x02,0x00,0x00,0x71,0x08,0x00, 0x02,0x02,0x00,0x06,0xfe,0x02,0xf8,0x00,0x0c,0xf6, 0x03,0x8f,0x00,0x71,0x07,0x00,0x02,0x02,0x00,0x06, 0xfe,0x02,0xf9,0x00,0x0c,0x85,0x00,0x71,0x02,0x80, 0x03,0x8f,0x00,0x71,0x07,0x00,0x03,0x02,0x00,0x06, 0xfd,0x02,0xf9,0x00,0x0c,0xf6,0x03,0x8d,0x02,0x02, 0x06,0x00,0x02,0x7e,0x00,0x75,0xfe,0x7e,0xfa,0x00, 0xfe,0x02,0x04,0x85,0x06,0x00,0x02,0xf9,0x03,0x80, 0x00,0x0f,0x00,0xf8,0x04,0x00,0x00,0x06,0x02,0x02, 0x04,0x00,0x02,0x7e,0x00,0x75,0xfe,0x7e,0xfc,0x00, 0xfe,0x02,0x00,0x05,0x0a,0xf9,0x0d,0x80,0x00,0x0f, 0xf7,0x00,0xff,0x7e,0x00,0x7b,0x01,0x7e,0x09,0x00, 0xf6,0xfa,0x04,0x06,0x08,0xfa }; //------------------------------------------------------------------------- gsv_text::~gsv_text() { if(m_loaded_font) delete [] m_loaded_font; if(m_text_buf) delete [] m_text_buf; } //------------------------------------------------------------------------- gsv_text::gsv_text() : m_x(0.0), m_y(0.0), m_start_x(0.0), m_width(10.0), m_height(0.0), m_space(0.0), m_line_space(0.0), m_text(m_chr), m_text_buf(0), m_buf_size(0), m_cur_chr(m_chr), m_font(gsv_default_font), m_loaded_font(0), m_status(initial), m_big_endian(false), m_flip(false) { m_chr[0] = m_chr[1] = 0; int t = 1; if(*(char*)&t == 0) m_big_endian = true; } //------------------------------------------------------------------------- void gsv_text::font(const void* font) { m_font = font; if(m_font == 0) m_font = m_loaded_font; } //------------------------------------------------------------------------- void gsv_text::size(double height, double width) { m_height = height; m_width = width; } //------------------------------------------------------------------------- void gsv_text::space(double space) { m_space = space; } //------------------------------------------------------------------------- void gsv_text::line_space(double line_space) { m_line_space = line_space; } //------------------------------------------------------------------------- void gsv_text::start_point(double x, double y) { m_x = m_start_x = x; m_y = y; //if(m_flip) m_y += m_height; } //------------------------------------------------------------------------- void gsv_text::load_font(const char* file) { if(m_loaded_font) delete [] m_loaded_font; m_loaded_font = 0; FILE* fd = fopen(file, "rb"); if(fd) { unsigned len; fseek(fd, 0l, SEEK_END); len = ftell(fd); fseek(fd, 0l, SEEK_SET); if(len > 0) { m_loaded_font = new char [len]; fread(m_loaded_font, 1, len, fd); m_font = m_loaded_font; } fclose(fd); } } //------------------------------------------------------------------------- void gsv_text::text(const char* text) { if(text == 0) { m_chr[0] = 0; m_text = m_chr; return; } unsigned new_size = strlen(text) + 1; if(new_size > m_buf_size) { if(m_text_buf) delete [] m_text_buf; m_text_buf = new char [m_buf_size = new_size]; } memcpy(m_text_buf, text, new_size); m_text = m_text_buf; } //------------------------------------------------------------------------- void gsv_text::rewind(unsigned) { m_status = initial; if(m_font == 0) return; m_indices = (int8u*)m_font; double base_height = value(m_indices + 4); m_indices += value(m_indices); m_glyphs = (int8*)(m_indices + 257*2); m_h = m_height / base_height; m_w = (m_width == 0.0) ? m_h : m_width / base_height; if(m_flip) m_h = -m_h; m_cur_chr = m_text; } //------------------------------------------------------------------------- unsigned gsv_text::vertex(double* x, double* y) { unsigned idx; int8 yc, yf; int dx, dy; bool quit = false; while(!quit) { switch(m_status) { case initial: if(m_font == 0) { quit = true; break; } m_status = next_char; case next_char: if(*m_cur_chr == 0) { quit = true; break; } idx = (*m_cur_chr++) & 0xFF; if(idx == '\n') { m_x = m_start_x; m_y -= m_flip ? -m_height - m_line_space : m_height + m_line_space; break; } idx <<= 1; m_bglyph = m_glyphs + value(m_indices + idx); m_eglyph = m_glyphs + value(m_indices + idx + 2); m_status = start_glyph; case start_glyph: *x = m_x; *y = m_y; m_status = glyph; return path_cmd_move_to; case glyph: if(m_bglyph >= m_eglyph) { m_status = next_char; m_x += m_space; break; } dx = int(*m_bglyph++); yf = (yc = *m_bglyph++) & 0x80; yc <<= 1; yc >>= 1; dy = int(yc); m_x += double(dx) * m_w; m_y += double(dy) * m_h; *x = m_x; *y = m_y; return yf ? path_cmd_move_to : path_cmd_line_to; } } return path_cmd_stop; } } aggdraw-1.3.14/agg2/src/agg_image_filters.cpp000066400000000000000000000067751417726601400210060ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Filtering class image_filter_base implemantation // //---------------------------------------------------------------------------- #include "agg_image_filters.h" namespace agg { //-------------------------------------------------------------------- image_filter_base::~image_filter_base() { delete [] m_weight_array_int; delete [] m_weight_array_dbl; } //-------------------------------------------------------------------- image_filter_base::image_filter_base(unsigned dimension) : m_dimension(dimension), m_start(-int(dimension / 2 - 1)), m_weight_array_dbl(new double [dimension << image_subpixel_shift]), m_weight_array_int(new int [dimension << image_subpixel_shift]) { } //-------------------------------------------------------------------- void image_filter_base::weight(unsigned idx, double val) { m_weight_array_dbl[idx] = val; m_weight_array_int[idx] = int(val * image_filter_size); } //-------------------------------------------------------------------- double image_filter_base::calc_x(unsigned idx) const { return double(idx) / double(image_subpixel_size) - double(m_dimension / 2); } //-------------------------------------------------------------------- // This function normalizes integer values and corrects the rounding // errors. It doesn't do anything with the source floating point values // (m_weight_array_dbl), it corrects only integers according to the rule // of 1.0 which means that any sum of pixel weights must be equal to 1.0. // So, the filter function must produce a graph of the proper shape. //-------------------------------------------------------------------- void image_filter_base::normalize() { unsigned i; int flip = 1; for(i = 0; i < image_subpixel_size; i++) { for(;;) { int sum = 0; unsigned j; for(j = 0; j < m_dimension; j++) { sum += m_weight_array_int[j * image_subpixel_size + i]; } sum -= image_filter_size; if(sum == 0) break; int inc = (sum > 0) ? -1 : 1; for(j = 0; j < m_dimension && sum; j++) { flip ^= 1; unsigned idx = flip ? m_dimension/2 + j/2 : m_dimension/2 - j/2; int v = m_weight_array_int[idx * image_subpixel_size + i]; if(v < image_filter_size) { m_weight_array_int[idx * image_subpixel_size + i] += inc; sum += inc; } } } } } } aggdraw-1.3.14/agg2/src/agg_line_aa_basics.cpp000066400000000000000000000056771417726601400211100ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #include #include "agg_line_aa_basics.h" namespace agg { //------------------------------------------------------------------------- // The number of the octant is determined as a 3-bit value as follows: // bit 0 = vertical flag // bit 1 = sx < 0 // bit 2 = sy < 0 // // [N] shows the number of the orthogonal quadrant // shows the number of the diagonal quadrant // <1> // [1] | [0] // . (3)011 | 001(1) . // . | . // . | . // . | . // (2)010 .|. 000(0) // <2> ----------.+.----------- <0> // (6)110 . | . 100(4) // . | . // . | . // . | . // (7)111 | 101(5) // [2] | [3] // <3> // 0,1,2,3,4,5,6,7 int8u line_parameters::s_orthogonal_quadrant[8] = { 0,0,1,1,3,3,2,2 }; int8u line_parameters::s_diagonal_quadrant[8] = { 0,1,2,1,0,3,2,3 }; //------------------------------------------------------------------------- void bisectrix(const line_parameters& l1, const line_parameters& l2, int* x, int* y) { double k = double(l2.len) / double(l1.len); double tx = l2.x2 - (l2.x1 - l1.x1) * k; double ty = l2.y2 - (l2.y1 - l1.y1) * k; //All bisectrices must be on the right of the line //If the next point is on the left (l1 => l2.2) //then the bisectix should be rotated by 180 degrees. if(double(l2.x2 - l2.x1) * double(l2.y1 - l1.y1) < double(l2.y2 - l2.y1) * double(l2.x1 - l1.x1) + 100.0) { tx -= (tx - l2.x1) * 2.0; ty -= (ty - l2.y1) * 2.0; } // Check if the bisectrix is too short double dx = tx - l2.x1; double dy = ty - l2.y1; if((int)sqrt(dx * dx + dy * dy) < line_subpixel_size) { tx = (l2.x1 + l2.x1 + (l2.y1 - l1.y1) + (l2.y2 - l2.y1)) / 2; ty = (l2.y1 + l2.y1 - (l2.x1 - l1.x1) - (l2.x2 - l2.x1)) / 2; } *x = int(tx); *y = int(ty); } } aggdraw-1.3.14/agg2/src/agg_line_profile_aa.cpp000066400000000000000000000067561417726601400213030ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #include "agg_renderer_outline_aa.h" namespace agg { //--------------------------------------------------------------------- void line_profile_aa::width(double w) { if(w < 0.0) w = 0.0; if(w < m_smoother_width) w += w; else w += m_smoother_width; w *= 0.5; w -= m_smoother_width; double s = m_smoother_width; if(w < 0.0) { s += w; w = 0.0; } set(w, s); } //--------------------------------------------------------------------- line_profile_aa::value_type* line_profile_aa::profile(double w) { m_subpixel_width = int(w * subpixel_size); unsigned size = m_subpixel_width + subpixel_size * 6; if(size > m_size) { delete [] m_profile; m_profile = new value_type[m_size = size]; } return m_profile; } //--------------------------------------------------------------------- void line_profile_aa::set(double center_width, double smoother_width) { double base_val = 1.0; if(center_width == 0.0) center_width = 1.0 / subpixel_size; if(smoother_width == 0.0) smoother_width = 1.0 / subpixel_size; double width = center_width + smoother_width; if(width < m_min_width) { double k = width / m_min_width; base_val *= k; center_width /= k; smoother_width /= k; } value_type* ch = profile(center_width + smoother_width); unsigned subpixel_center_width = unsigned(center_width * subpixel_size); unsigned subpixel_smoother_width = unsigned(smoother_width * subpixel_size); value_type* ch_center = ch + subpixel_size*2; value_type* ch_smoother = ch_center + subpixel_center_width; unsigned i; unsigned val = m_gamma[unsigned(base_val * aa_mask)]; ch = ch_center; for(i = 0; i < subpixel_center_width; i++) { *ch++ = (value_type)val; } for(i = 0; i < subpixel_smoother_width; i++) { *ch_smoother++ = m_gamma[unsigned((base_val - base_val * (double(i) / subpixel_smoother_width)) * aa_mask)]; } unsigned n_smoother = profile_size() - subpixel_smoother_width - subpixel_center_width - subpixel_size*2; val = m_gamma[0]; for(i = 0; i < n_smoother; i++) { *ch_smoother++ = (value_type)val; } ch = ch_center; for(i = 0; i < subpixel_size*2; i++) { *--ch = *ch_center++; } } } aggdraw-1.3.14/agg2/src/agg_path_storage.cpp000066400000000000000000000367461417726601400206550ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Class path_storage // //---------------------------------------------------------------------------- #include #include #include "agg_path_storage.h" #include "agg_math.h" #include "agg_bezier_arc.h" namespace agg { //------------------------------------------------------------------------ path_storage::~path_storage() { if(m_total_blocks) { double** coord_blk = m_coord_blocks + m_total_blocks - 1; while(m_total_blocks--) { delete [] *coord_blk; --coord_blk; } delete [] m_coord_blocks; } } //------------------------------------------------------------------------ path_storage::path_storage() : m_total_vertices(0), m_total_blocks(0), m_max_blocks(0), m_coord_blocks(0), m_cmd_blocks(0), m_iterator(0) { } //------------------------------------------------------------------------ path_storage::path_storage(const path_storage& ps) : m_total_vertices(0), m_total_blocks(0), m_max_blocks(0), m_coord_blocks(0), m_cmd_blocks(0), m_iterator(0) { copy_from(ps); } //------------------------------------------------------------------------ void path_storage::remove_all() { m_total_vertices = 0; m_iterator = 0; } //------------------------------------------------------------------------ void path_storage::copy_from(const path_storage& ps) { remove_all(); unsigned i; for(i = 0; i < ps.total_vertices(); i++) { double x, y; unsigned cmd = ps.vertex(i, &x, &y); add_vertex(x, y, cmd); } } //------------------------------------------------------------------------ void path_storage::allocate_block(unsigned nb) { if(nb >= m_max_blocks) { double** new_coords = new double* [(m_max_blocks + block_pool) * 2]; unsigned char** new_cmds = (unsigned char**)(new_coords + m_max_blocks + block_pool); if(m_coord_blocks) { memcpy(new_coords, m_coord_blocks, m_max_blocks * sizeof(double*)); memcpy(new_cmds, m_cmd_blocks, m_max_blocks * sizeof(unsigned char*)); delete [] m_coord_blocks; } m_coord_blocks = new_coords; m_cmd_blocks = new_cmds; m_max_blocks += block_pool; } m_coord_blocks[nb] = new double [block_size * 2 + block_size / (sizeof(double) / sizeof(unsigned char))]; m_cmd_blocks[nb] = (unsigned char*)(m_coord_blocks[nb] + block_size * 2); m_total_blocks++; } //------------------------------------------------------------------------ void path_storage::rewind(unsigned path_id) { m_iterator = path_id; } //------------------------------------------------------------------------ void path_storage::arc_to(double rx, double ry, double angle, bool large_arc_flag, bool sweep_flag, double x, double y) { if(m_total_vertices && is_vertex(command(m_total_vertices - 1))) { const double epsilon = 1e-30; double x0 = 0.0; double y0 = 0.0; last_vertex(&x0, &y0); rx = fabs(rx); ry = fabs(ry); // Ensure radii are valid //------------------------- if(rx < epsilon || ry < epsilon) { line_to(x, y); return; } if(calc_distance(x0, y0, x, y) < epsilon) { // If the endpoints (x, y) and (x0, y0) are identical, then this // is equivalent to omitting the elliptical arc segment entirely. return; } bezier_arc_svg a(x0, y0, rx, ry, angle, large_arc_flag, sweep_flag, x, y); if(a.radii_ok()) { add_path(a, 0, true); } else { line_to(x, y); } } else { move_to(x, y); } } //------------------------------------------------------------------------ void path_storage::arc_rel(double rx, double ry, double angle, bool large_arc_flag, bool sweep_flag, double dx, double dy) { rel_to_abs(&dx, &dy); arc_to(rx, ry, angle, large_arc_flag, sweep_flag, dx, dy); } //------------------------------------------------------------------------ void path_storage::curve3(double x_ctrl, double y_ctrl, double x_to, double y_to) { add_vertex(x_ctrl, y_ctrl, path_cmd_curve3); add_vertex(x_to, y_to, path_cmd_curve3); } //------------------------------------------------------------------------ void path_storage::curve3_rel(double dx_ctrl, double dy_ctrl, double dx_to, double dy_to) { rel_to_abs(&dx_ctrl, &dy_ctrl); rel_to_abs(&dx_to, &dy_to); add_vertex(dx_ctrl, dy_ctrl, path_cmd_curve3); add_vertex(dx_to, dy_to, path_cmd_curve3); } //------------------------------------------------------------------------ void path_storage::curve3(double x_to, double y_to) { double x0; double y0; if(is_vertex(last_vertex(&x0, &y0))) { double x_ctrl; double y_ctrl; unsigned cmd = prev_vertex(&x_ctrl, &y_ctrl); if(is_curve(cmd)) { x_ctrl = x0 + x0 - x_ctrl; y_ctrl = y0 + y0 - y_ctrl; } else { x_ctrl = x0; y_ctrl = y0; } curve3(x_ctrl, x_ctrl, x_to, y_to); } } //------------------------------------------------------------------------ void path_storage::curve3_rel(double dx_to, double dy_to) { rel_to_abs(&dx_to, &dy_to); curve3(dx_to, dy_to); } //------------------------------------------------------------------------ void path_storage::curve4(double x_ctrl1, double y_ctrl1, double x_ctrl2, double y_ctrl2, double x_to, double y_to) { add_vertex(x_ctrl1, y_ctrl1, path_cmd_curve4); add_vertex(x_ctrl2, y_ctrl2, path_cmd_curve4); add_vertex(x_to, y_to, path_cmd_curve4); } //------------------------------------------------------------------------ void path_storage::curve4_rel(double dx_ctrl1, double dy_ctrl1, double dx_ctrl2, double dy_ctrl2, double dx_to, double dy_to) { rel_to_abs(&dx_ctrl1, &dy_ctrl1); rel_to_abs(&dx_ctrl2, &dy_ctrl2); rel_to_abs(&dx_to, &dy_to); add_vertex(dx_ctrl1, dy_ctrl1, path_cmd_curve4); add_vertex(dx_ctrl2, dy_ctrl2, path_cmd_curve4); add_vertex(dx_to, dy_to, path_cmd_curve4); } //------------------------------------------------------------------------ void path_storage::curve4(double x_ctrl2, double y_ctrl2, double x_to, double y_to) { double x0; double y0; if(is_vertex(last_vertex(&x0, &y0))) { double x_ctrl1; double y_ctrl1; unsigned cmd = prev_vertex(&x_ctrl1, &y_ctrl1); if(is_curve(cmd)) { x_ctrl1 = x0 + x0 - x_ctrl1; y_ctrl1 = y0 + y0 - y_ctrl1; } else { x_ctrl1 = x0; y_ctrl1 = y0; } curve4(x_ctrl1, y_ctrl1, x_ctrl2, y_ctrl2, x_to, y_to); } } //------------------------------------------------------------------------ void path_storage::curve4_rel(double dx_ctrl2, double dy_ctrl2, double dx_to, double dy_to) { rel_to_abs(&dx_ctrl2, &dy_ctrl2); rel_to_abs(&dx_to, &dy_to); curve4(dx_ctrl2, dy_ctrl2, dx_to, dy_to); } //------------------------------------------------------------------------ void path_storage::end_poly(unsigned flags) { if(m_total_vertices) { if(is_vertex(command(m_total_vertices - 1))) { add_vertex(0.0, 0.0, path_cmd_end_poly | flags); } } } //------------------------------------------------------------------------ unsigned path_storage::start_new_path() { if(m_total_vertices) { if(!is_stop(command(m_total_vertices - 1))) { add_vertex(0.0, 0.0, path_cmd_stop); } } return m_total_vertices; } //------------------------------------------------------------------------ void path_storage::add_poly(const double* vertices, unsigned num, bool solid_path, unsigned end_flags) { if(num) { if(!solid_path) { move_to(vertices[0], vertices[1]); vertices += 2; --num; } while(num--) { line_to(vertices[0], vertices[1]); vertices += 2; } if(end_flags) end_poly(end_flags); } } //------------------------------------------------------------------------ unsigned path_storage::perceive_polygon_orientation(unsigned idx, double xs, double ys, unsigned* orientation) { unsigned i; double sum = 0.0; double x, y, xn, yn; x = xs; y = ys; for(i = idx; i < m_total_vertices; ++i) { if(is_next_poly(vertex(i, &xn, &yn))) break; sum += x * yn - y * xn; x = xn; y = yn; } if(i > idx) sum += x * ys - y * xs; *orientation = path_flags_none; if(sum != 0.0) { *orientation = (sum < 0.0) ? path_flags_cw : path_flags_ccw; } return i; } //------------------------------------------------------------------------ void path_storage::reverse_polygon(unsigned start, unsigned end) { unsigned i; unsigned tmp_cmd = command(start); // Shift all commands to one position for(i = start; i < end; i++) { modify_command(i, command(i + 1)); } // Assign starting command to the ending command modify_command(end, tmp_cmd); // Reverse the polygon while(end > start) { unsigned start_nb = start >> block_shift; unsigned end_nb = end >> block_shift; double* start_ptr = m_coord_blocks[start_nb] + ((start & block_mask) << 1); double* end_ptr = m_coord_blocks[end_nb] + ((end & block_mask) << 1); double tmp_xy; tmp_xy = *start_ptr; *start_ptr++ = *end_ptr; *end_ptr++ = tmp_xy; tmp_xy = *start_ptr; *start_ptr = *end_ptr; *end_ptr = tmp_xy; tmp_cmd = m_cmd_blocks[start_nb][start & block_mask]; m_cmd_blocks[start_nb][start & block_mask] = m_cmd_blocks[end_nb][end & block_mask]; m_cmd_blocks[end_nb][end & block_mask] = (unsigned char)tmp_cmd; ++start; --end; } } //------------------------------------------------------------------------ unsigned path_storage::arrange_orientations(unsigned path_id, path_flags_e new_orientation) { unsigned end = m_total_vertices; if(m_total_vertices && new_orientation != path_flags_none) { unsigned start = path_id; double xs, ys; unsigned cmd = vertex(start, &xs, &ys); unsigned inc = 0; for(;;) { unsigned orientation; end = perceive_polygon_orientation(start + 1, xs, ys, &orientation); if(end > start + 2 && orientation && orientation != unsigned(new_orientation)) { reverse_polygon(start + inc, end - 1); } if(end >= m_total_vertices) break; cmd = command(end); if(is_stop(cmd)) { ++end; break; } if(is_end_poly(cmd)) { inc = 1; modify_command(end, set_orientation(cmd, new_orientation)); } else { cmd = vertex(++end, &xs, &ys); inc = 0; } start = end; } } return end; } //------------------------------------------------------------------------ void path_storage::arrange_orientations_all_paths(path_flags_e new_orientation) { if(new_orientation != path_flags_none) { unsigned start = 0; while(start < m_total_vertices) { start = arrange_orientations(start, new_orientation); } } } //------------------------------------------------------------------------ void path_storage::flip_x(double x1, double x2) { unsigned i; double x, y; for(i = 0; i < m_total_vertices; i++) { unsigned cmd = vertex(i, &x, &y); if(is_vertex(cmd)) { modify_vertex(i, x2 - x + x1, y); } } } //------------------------------------------------------------------------ void path_storage::flip_y(double y1, double y2) { unsigned i; double x, y; for(i = 0; i < m_total_vertices; i++) { unsigned cmd = vertex(i, &x, &y); if(is_vertex(cmd)) { modify_vertex(i, x, y2 - y + y1); } } } } aggdraw-1.3.14/agg2/src/agg_rasterizer_scanline_aa.cpp000066400000000000000000000400311417726601400226620ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // // The author gratefully acknowleges the support of David Turner, // Robert Wilhelm, and Werner Lemberg - the authors of the FreeType // libray - in producing this work. See http://www.freetype.org for details. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Class outline_aa - implementation. // // Initially the rendering algorithm was designed by David Turner and the // other authors of the FreeType library - see the above notice. I nearly // created a similar renderer, but still I was far from David's work. // I completely redesigned the original code and adapted it for Anti-Grain // ideas. Two functions - render_line and render_hline are the core of // the algorithm - they calculate the exact coverage of each pixel cell // of the polygon. I left these functions almost as is, because there's // no way to improve the perfection - hats off to David and his group! // // All other code is very different from the original. // //---------------------------------------------------------------------------- #include #include "agg_rasterizer_scanline_aa.h" namespace agg { //------------------------------------------------------------------------ inline void cell_aa::set_cover(int c, int a) { cover = c; area = a; } //------------------------------------------------------------------------ inline void cell_aa::add_cover(int c, int a) { cover += c; area += a; } //------------------------------------------------------------------------ inline void cell_aa::set_coord(int cx, int cy) { x = int16(cx); y = int16(cy); packed_coord = (cy << 16) + cx; } //------------------------------------------------------------------------ inline void cell_aa::set(int cx, int cy, int c, int a) { x = int16(cx); y = int16(cy); packed_coord = (cy << 16) + cx; cover = c; area = a; } //------------------------------------------------------------------------ outline_aa::~outline_aa() { delete [] m_sorted_cells; if(m_num_blocks) { cell_aa** ptr = m_cells + m_num_blocks - 1; while(m_num_blocks--) { delete [] *ptr; ptr--; } delete [] m_cells; } } //------------------------------------------------------------------------ outline_aa::outline_aa() : m_num_blocks(0), m_max_blocks(0), m_cur_block(0), m_num_cells(0), m_cells(0), m_cur_cell_ptr(0), m_sorted_cells(0), m_sorted_size(0), m_cur_x(0), m_cur_y(0), m_min_x(0x7FFFFFFF), m_min_y(0x7FFFFFFF), m_max_x(-0x7FFFFFFF), m_max_y(-0x7FFFFFFF), m_sorted(false) { m_cur_cell.set(0x7FFF, 0x7FFF, 0, 0); } //------------------------------------------------------------------------ void outline_aa::reset() { m_num_cells = 0; m_cur_block = 0; m_cur_cell.set(0x7FFF, 0x7FFF, 0, 0); m_sorted = false; m_min_x = 0x7FFFFFFF; m_min_y = 0x7FFFFFFF; m_max_x = -0x7FFFFFFF; m_max_y = -0x7FFFFFFF; } //------------------------------------------------------------------------ void outline_aa::allocate_block() { if(m_cur_block >= m_num_blocks) { if(m_num_blocks >= m_max_blocks) { cell_aa** new_cells = new cell_aa* [m_max_blocks + cell_block_pool]; if(m_cells) { memcpy(new_cells, m_cells, m_max_blocks * sizeof(cell_aa*)); delete [] m_cells; } m_cells = new_cells; m_max_blocks += cell_block_pool; } m_cells[m_num_blocks++] = new cell_aa [unsigned(cell_block_size)]; } m_cur_cell_ptr = m_cells[m_cur_block++]; } //------------------------------------------------------------------------ inline void outline_aa::add_cur_cell() { if(m_cur_cell.area | m_cur_cell.cover) { if((m_num_cells & cell_block_mask) == 0) { if(m_num_blocks >= cell_block_limit) return; allocate_block(); } *m_cur_cell_ptr++ = m_cur_cell; ++m_num_cells; if(m_cur_cell.x < m_min_x) m_min_x = m_cur_cell.x; if(m_cur_cell.x > m_max_x) m_max_x = m_cur_cell.x; } } //------------------------------------------------------------------------ inline void outline_aa::set_cur_cell(int x, int y) { if(m_cur_cell.packed_coord != (y << 16) + x) { add_cur_cell(); m_cur_cell.set(x, y, 0, 0); } } //------------------------------------------------------------------------ inline void outline_aa::render_hline(int ey, int x1, int y1, int x2, int y2) { int ex1 = x1 >> poly_base_shift; int ex2 = x2 >> poly_base_shift; int fx1 = x1 & poly_base_mask; int fx2 = x2 & poly_base_mask; int delta, p, first, dx; int incr, lift, mod, rem; //trivial case. Happens often if(y1 == y2) { set_cur_cell(ex2, ey); return; } //everything is located in a single cell. That is easy! if(ex1 == ex2) { delta = y2 - y1; m_cur_cell.add_cover(delta, (fx1 + fx2) * delta); return; } //ok, we'll have to render a run of adjacent cells on the same //hline... p = (poly_base_size - fx1) * (y2 - y1); first = poly_base_size; incr = 1; dx = x2 - x1; if(dx < 0) { p = fx1 * (y2 - y1); first = 0; incr = -1; dx = -dx; } delta = p / dx; mod = p % dx; if(mod < 0) { delta--; mod += dx; } m_cur_cell.add_cover(delta, (fx1 + first) * delta); ex1 += incr; set_cur_cell(ex1, ey); y1 += delta; if(ex1 != ex2) { p = poly_base_size * (y2 - y1 + delta); lift = p / dx; rem = p % dx; if (rem < 0) { lift--; rem += dx; } mod -= dx; while (ex1 != ex2) { delta = lift; mod += rem; if(mod >= 0) { mod -= dx; delta++; } m_cur_cell.add_cover(delta, (poly_base_size) * delta); y1 += delta; ex1 += incr; set_cur_cell(ex1, ey); } } delta = y2 - y1; m_cur_cell.add_cover(delta, (fx2 + poly_base_size - first) * delta); } //------------------------------------------------------------------------ void outline_aa::render_line(int x1, int y1, int x2, int y2) { int ey1 = y1 >> poly_base_shift; int ey2 = y2 >> poly_base_shift; int fy1 = y1 & poly_base_mask; int fy2 = y2 & poly_base_mask; int dx, dy, x_from, x_to; int p, rem, mod, lift, delta, first, incr; dx = x2 - x1; dy = y2 - y1; //everything is on a single hline if(ey1 == ey2) { render_hline(ey1, x1, fy1, x2, fy2); return; } //Vertical line - we have to calculate start and end cells, //and then - the common values of the area and coverage for //all cells of the line. We know exactly there's only one //cell, so, we don't have to call render_hline(). incr = 1; if(dx == 0) { int ex = x1 >> poly_base_shift; int two_fx = (x1 - (ex << poly_base_shift)) << 1; int area; first = poly_base_size; if(dy < 0) { first = 0; incr = -1; } x_from = x1; //render_hline(ey1, x_from, fy1, x_from, first); delta = first - fy1; m_cur_cell.add_cover(delta, two_fx * delta); ey1 += incr; set_cur_cell(ex, ey1); delta = first + first - poly_base_size; area = two_fx * delta; while(ey1 != ey2) { //render_hline(ey1, x_from, poly_base_size - first, x_from, first); m_cur_cell.set_cover(delta, area); ey1 += incr; set_cur_cell(ex, ey1); } //render_hline(ey1, x_from, poly_base_size - first, x_from, fy2); delta = fy2 - poly_base_size + first; m_cur_cell.add_cover(delta, two_fx * delta); return; } //ok, we have to render several hlines p = (poly_base_size - fy1) * dx; first = poly_base_size; if(dy < 0) { p = fy1 * dx; first = 0; incr = -1; dy = -dy; } delta = p / dy; mod = p % dy; if(mod < 0) { delta--; mod += dy; } x_from = x1 + delta; render_hline(ey1, x1, fy1, x_from, first); ey1 += incr; set_cur_cell(x_from >> poly_base_shift, ey1); if(ey1 != ey2) { p = poly_base_size * dx; lift = p / dy; rem = p % dy; if(rem < 0) { lift--; rem += dy; } mod -= dy; while(ey1 != ey2) { delta = lift; mod += rem; if (mod >= 0) { mod -= dy; delta++; } x_to = x_from + delta; render_hline(ey1, x_from, poly_base_size - first, x_to, first); x_from = x_to; ey1 += incr; set_cur_cell(x_from >> poly_base_shift, ey1); } } render_hline(ey1, x_from, poly_base_size - first, x2, fy2); } //------------------------------------------------------------------------ void outline_aa::move_to(int x, int y) { if(m_sorted) reset(); set_cur_cell(x >> poly_base_shift, y >> poly_base_shift); m_cur_x = x; m_cur_y = y; } //------------------------------------------------------------------------ void outline_aa::line_to(int x, int y) { render_line(m_cur_x, m_cur_y, x, y); m_cur_x = x; m_cur_y = y; m_sorted = false; } //------------------------------------------------------------------------ enum { qsort_threshold = 9 }; //------------------------------------------------------------------------ template static inline void swap_cells(T* a, T* b) { T temp = *a; *a = *b; *b = temp; } //------------------------------------------------------------------------ template static inline bool less_than(T* a, T* b) { return (*a)->packed_coord < (*b)->packed_coord; } //------------------------------------------------------------------------ void outline_aa::qsort_cells(cell_aa** start, unsigned num) { cell_aa** stack[80]; cell_aa*** top; cell_aa** limit; cell_aa** base; limit = start + num; base = start; top = stack; for (;;) { int len = int(limit - base); cell_aa** i; cell_aa** j; cell_aa** pivot; if(len > qsort_threshold) { // we use base + len/2 as the pivot pivot = base + len / 2; swap_cells(base, pivot); i = base + 1; j = limit - 1; // now ensure that *i <= *base <= *j if(less_than(j, i)) { swap_cells(i, j); } if(less_than(base, i)) { swap_cells(base, i); } if(less_than(j, base)) { swap_cells(base, j); } for(;;) { do i++; while( less_than(i, base) ); do j--; while( less_than(base, j) ); if ( i > j ) { break; } swap_cells(i, j); } swap_cells(base, j); // now, push the largest sub-array if(j - base > limit - i) { top[0] = base; top[1] = j; base = i; } else { top[0] = i; top[1] = limit; limit = j; } top += 2; } else { // the sub-array is small, perform insertion sort j = base; i = j + 1; for(; i < limit; j = i, i++) { for(; less_than(j + 1, j); j--) { swap_cells(j + 1, j); if (j == base) { break; } } } if(top > stack) { top -= 2; base = top[0]; limit = top[1]; } else { break; } } } } //------------------------------------------------------------------------ void outline_aa::sort_cells() { if(m_num_cells == 0) return; if(m_num_cells > m_sorted_size) { delete [] m_sorted_cells; m_sorted_size = m_num_cells; m_sorted_cells = new cell_aa* [m_num_cells + 1]; } cell_aa** sorted_ptr = m_sorted_cells; cell_aa** block_ptr = m_cells; cell_aa* cell_ptr; unsigned nb = m_num_cells >> cell_block_shift; unsigned i; while(nb--) { cell_ptr = *block_ptr++; i = cell_block_size; while(i--) { *sorted_ptr++ = cell_ptr++; } } cell_ptr = *block_ptr++; i = m_num_cells & cell_block_mask; while(i--) { *sorted_ptr++ = cell_ptr++; } m_sorted_cells[m_num_cells] = 0; qsort_cells(m_sorted_cells, m_num_cells); m_min_y = m_sorted_cells[0]->y; m_max_y = m_sorted_cells[m_num_cells - 1]->y; } //------------------------------------------------------------------------ const cell_aa* const* outline_aa::cells() { //Perform sort only the first time. if(!m_sorted) { add_cur_cell(); sort_cells(); m_sorted = true; } return m_sorted_cells; } } aggdraw-1.3.14/agg2/src/agg_rounded_rect.cpp000066400000000000000000000121201417726601400206260ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Rounded rectangle vertex generator // //---------------------------------------------------------------------------- #include #include "agg_rounded_rect.h" namespace agg { //------------------------------------------------------------------------ rounded_rect::rounded_rect(double x1, double y1, double x2, double y2, double r) : m_x1(x1), m_y1(y1), m_x2(x2), m_y2(y2), m_rx1(r), m_ry1(r), m_rx2(r), m_ry2(r), m_rx3(r), m_ry3(r), m_rx4(r), m_ry4(r) { if(x1 > x2) { m_x1 = x2; m_x2 = x1; } if(y1 > y2) { m_y1 = y2; m_y2 = y1; } } //-------------------------------------------------------------------- void rounded_rect::rect(double x1, double y1, double x2, double y2) { m_x1 = x1; m_y1 = y1; m_x2 = x2; m_y2 = y2; if(x1 > x2) { m_x1 = x2; m_x2 = x1; } if(y1 > y2) { m_y1 = y2; m_y2 = y1; } } //-------------------------------------------------------------------- void rounded_rect::radius(double r) { m_rx1 = m_ry1 = m_rx2 = m_ry2 = m_rx3 = m_ry3 = m_rx4 = m_ry4 = r; } //-------------------------------------------------------------------- void rounded_rect::radius(double rx, double ry) { m_rx1 = m_rx2 = m_rx3 = m_rx4 = rx; m_ry1 = m_ry2 = m_ry3 = m_ry4 = ry; } //-------------------------------------------------------------------- void rounded_rect::radius(double rx_bottom, double ry_bottom, double rx_top, double ry_top) { m_rx1 = m_rx2 = rx_bottom; m_rx3 = m_rx4 = rx_top; m_ry1 = m_ry2 = ry_bottom; m_ry3 = m_ry4 = ry_top; } //-------------------------------------------------------------------- void rounded_rect::radius(double rx1, double ry1, double rx2, double ry2, double rx3, double ry3, double rx4, double ry4) { m_rx1 = rx1; m_ry1 = ry1; m_rx2 = rx2; m_ry2 = ry2; m_rx3 = rx3; m_ry3 = ry3; m_rx4 = rx4; m_ry4 = ry4; } //-------------------------------------------------------------------- void rounded_rect::normalize_radius() { double dx = fabs(m_y2 - m_y1); double dy = fabs(m_x2 - m_x1); double k = 1.0; double t; t = dx / (m_rx1 + m_rx2); if(t < k) k = t; t = dx / (m_rx3 + m_rx4); if(t < k) k = t; t = dy / (m_ry1 + m_ry2); if(t < k) k = t; t = dy / (m_ry3 + m_ry4); if(t < k) k = t; if(k < 1.0) { m_rx1 *= k; m_ry1 *= k; m_rx2 *= k; m_ry2 *= k; m_rx3 *= k; m_ry3 *= k; m_rx4 *= k; m_ry4 *= k; } } //-------------------------------------------------------------------- void rounded_rect::rewind(unsigned) { m_status = 0; } //-------------------------------------------------------------------- unsigned rounded_rect::vertex(double* x, double* y) { unsigned cmd = path_cmd_stop; switch(m_status) { case 0: m_arc.init(m_x1 + m_rx1, m_y1 + m_ry1, m_rx1, m_ry1, pi, pi+pi*0.5); m_arc.rewind(0); m_status++; case 1: cmd = m_arc.vertex(x, y); if(is_stop(cmd)) m_status++; else return cmd; case 2: m_arc.init(m_x2 - m_rx2, m_y1 + m_ry2, m_rx2, m_ry2, pi+pi*0.5, 0.0); m_arc.rewind(0); m_status++; case 3: cmd = m_arc.vertex(x, y); if(is_stop(cmd)) m_status++; else return path_cmd_line_to; case 4: m_arc.init(m_x2 - m_rx3, m_y2 - m_ry3, m_rx3, m_ry3, 0.0, pi*0.5); m_arc.rewind(0); m_status++; case 5: cmd = m_arc.vertex(x, y); if(is_stop(cmd)) m_status++; else return path_cmd_line_to; case 6: m_arc.init(m_x1 + m_rx4, m_y2 - m_ry4, m_rx4, m_ry4, pi*0.5, pi); m_arc.rewind(0); m_status++; case 7: cmd = m_arc.vertex(x, y); if(is_stop(cmd)) m_status++; else return path_cmd_line_to; case 8: cmd = path_cmd_end_poly | path_flags_close | path_flags_ccw; m_status++; break; } return cmd; } } aggdraw-1.3.14/agg2/src/agg_sqrt_tables.cpp000066400000000000000000000202461417726601400205040ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // static tables for fast integer sqrt // //---------------------------------------------------------------------------- #include "agg_basics.h" namespace agg { int16u g_sqrt_table[1024] = { 0, 2048,2896,3547,4096,4579,5017,5418,5793,6144,6476,6792,7094,7384,7663,7932,8192,8444, 8689,8927,9159,9385,9606,9822,10033,10240,10443,10642,10837,11029,11217,11403,11585, 11765,11942,12116,12288,12457,12625,12790,12953,13114,13273,13430,13585,13738,13890, 14040,14189,14336,14482,14626,14768,14910,15050,15188,15326,15462,15597,15731,15864, 15995,16126,16255,16384,16512,16638,16764,16888,17012,17135,17257,17378,17498,17618, 17736,17854,17971,18087,18203,18318,18432,18545,18658,18770,18882,18992,19102,19212, 19321,19429,19537,19644,19750,19856,19961,20066,20170,20274,20377,20480,20582,20684, 20785,20886,20986,21085,21185,21283,21382,21480,21577,21674,21771,21867,21962,22058, 22153,22247,22341,22435,22528,22621,22713,22806,22897,22989,23080,23170,23261,23351, 23440,23530,23619,23707,23796,23884,23971,24059,24146,24232,24319,24405,24491,24576, 24661,24746,24831,24915,24999,25083,25166,25249,25332,25415,25497,25580,25661,25743, 25824,25905,25986,26067,26147,26227,26307,26387,26466,26545,26624,26703,26781,26859, 26937,27015,27092,27170,27247,27324,27400,27477,27553,27629,27705,27780,27856,27931, 28006,28081,28155,28230,28304,28378,28452,28525,28599,28672,28745,28818,28891,28963, 29035,29108,29180,29251,29323,29394,29466,29537,29608,29678,29749,29819,29890,29960, 30030,30099,30169,30238,30308,30377,30446,30515,30583,30652,30720,30788,30856,30924, 30992,31059,31127,31194,31261,31328,31395,31462,31529,31595,31661,31727,31794,31859, 31925,31991,32056,32122,32187,32252,32317,32382,32446,32511,32575,32640,32704,32768, 32832,32896,32959,33023,33086,33150,33213,33276,33339,33402,33465,33527,33590,33652, 33714,33776,33839,33900,33962,34024,34086,34147,34208,34270,34331,34392,34453,34514, 34574,34635,34695,34756,34816,34876,34936,34996,35056,35116,35176,35235,35295,35354, 35413,35472,35531,35590,35649,35708,35767,35825,35884,35942,36001,36059,36117,36175, 36233,36291,36348,36406,36464,36521,36578,36636,36693,36750,36807,36864,36921,36978, 37034,37091,37147,37204,37260,37316,37372,37429,37485,37540,37596,37652,37708,37763, 37819,37874,37929,37985,38040,38095,38150,38205,38260,38315,38369,38424,38478,38533, 38587,38642,38696,38750,38804,38858,38912,38966,39020,39073,39127,39181,39234,39287, 39341,39394,39447,39500,39553,39606,39659,39712,39765,39818,39870,39923,39975,40028, 40080,40132,40185,40237,40289,40341,40393,40445,40497,40548,40600,40652,40703,40755, 40806,40857,40909,40960,41011,41062,41113,41164,41215,41266,41317,41368,41418,41469, 41519,41570,41620,41671,41721,41771,41821,41871,41922,41972,42021,42071,42121,42171, 42221,42270,42320,42369,42419,42468,42518,42567,42616,42665,42714,42763,42813,42861, 42910,42959,43008,43057,43105,43154,43203,43251,43300,43348,43396,43445,43493,43541, 43589,43637,43685,43733,43781,43829,43877,43925,43972,44020,44068,44115,44163,44210, 44258,44305,44352,44400,44447,44494,44541,44588,44635,44682,44729,44776,44823,44869, 44916,44963,45009,45056,45103,45149,45195,45242,45288,45334,45381,45427,45473,45519, 45565,45611,45657,45703,45749,45795,45840,45886,45932,45977,46023,46069,46114,46160, 46205,46250,46296,46341,46386,46431,46477,46522,46567,46612,46657,46702,46746,46791, 46836,46881,46926,46970,47015,47059,47104,47149,47193,47237,47282,47326,47370,47415, 47459,47503,47547,47591,47635,47679,47723,47767,47811,47855,47899,47942,47986,48030, 48074,48117,48161,48204,48248,48291,48335,48378,48421,48465,48508,48551,48594,48637, 48680,48723,48766,48809,48852,48895,48938,48981,49024,49067,49109,49152,49195,49237, 49280,49322,49365,49407,49450,49492,49535,49577,49619,49661,49704,49746,49788,49830, 49872,49914,49956,49998,50040,50082,50124,50166,50207,50249,50291,50332,50374,50416, 50457,50499,50540,50582,50623,50665,50706,50747,50789,50830,50871,50912,50954,50995, 51036,51077,51118,51159,51200,51241,51282,51323,51364,51404,51445,51486,51527,51567, 51608,51649,51689,51730,51770,51811,51851,51892,51932,51972,52013,52053,52093,52134, 52174,52214,52254,52294,52334,52374,52414,52454,52494,52534,52574,52614,52654,52694, 52734,52773,52813,52853,52892,52932,52972,53011,53051,53090,53130,53169,53209,53248, 53287,53327,53366,53405,53445,53484,53523,53562,53601,53640,53679,53719,53758,53797, 53836,53874,53913,53952,53991,54030,54069,54108,54146,54185,54224,54262,54301,54340, 54378,54417,54455,54494,54532,54571,54609,54647,54686,54724,54762,54801,54839,54877, 54915,54954,54992,55030,55068,55106,55144,55182,55220,55258,55296,55334,55372,55410, 55447,55485,55523,55561,55599,55636,55674,55712,55749,55787,55824,55862,55900,55937, 55975,56012,56049,56087,56124,56162,56199,56236,56273,56311,56348,56385,56422,56459, 56497,56534,56571,56608,56645,56682,56719,56756,56793,56830,56867,56903,56940,56977, 57014,57051,57087,57124,57161,57198,57234,57271,57307,57344,57381,57417,57454,57490, 57527,57563,57599,57636,57672,57709,57745,57781,57817,57854,57890,57926,57962,57999, 58035,58071,58107,58143,58179,58215,58251,58287,58323,58359,58395,58431,58467,58503, 58538,58574,58610,58646,58682,58717,58753,58789,58824,58860,58896,58931,58967,59002, 59038,59073,59109,59144,59180,59215,59251,59286,59321,59357,59392,59427,59463,59498, 59533,59568,59603,59639,59674,59709,59744,59779,59814,59849,59884,59919,59954,59989, 60024,60059,60094,60129,60164,60199,60233,60268,60303,60338,60373,60407,60442,60477, 60511,60546,60581,60615,60650,60684,60719,60753,60788,60822,60857,60891,60926,60960, 60995,61029,61063,61098,61132,61166,61201,61235,61269,61303,61338,61372,61406,61440, 61474,61508,61542,61576,61610,61644,61678,61712,61746,61780,61814,61848,61882,61916, 61950,61984,62018,62051,62085,62119,62153,62186,62220,62254,62287,62321,62355,62388, 62422,62456,62489,62523,62556,62590,62623,62657,62690,62724,62757,62790,62824,62857, 62891,62924,62957,62991,63024,63057,63090,63124,63157,63190,63223,63256,63289,63323, 63356,63389,63422,63455,63488,63521,63554,63587,63620,63653,63686,63719,63752,63785, 63817,63850,63883,63916,63949,63982,64014,64047,64080,64113,64145,64178,64211,64243, 64276,64309,64341,64374,64406,64439,64471,64504,64536,64569,64601,64634,64666,64699, 64731,64763,64796,64828,64861,64893,64925,64957,64990,65022,65054,65086,65119,65151, 65183,65215,65247,65279,65312,65344,65376,65408,65440,65472,65504 }; int8 g_elder_bit_table[256] = { 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,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, 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, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 }; } aggdraw-1.3.14/agg2/src/agg_trans_affine.cpp000066400000000000000000000140611417726601400206160ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Affine transformations // //---------------------------------------------------------------------------- #include "agg_trans_affine.h" namespace agg { //------------------------------------------------------------------------ const trans_affine& trans_affine::parl_to_parl(const double* src, const double* dst) { m0 = src[2] - src[0]; m1 = src[3] - src[1]; m2 = src[4] - src[0]; m3 = src[5] - src[1]; m4 = src[0]; m5 = src[1]; invert(); multiply(trans_affine(dst[2] - dst[0], dst[3] - dst[1], dst[4] - dst[0], dst[5] - dst[1], dst[0], dst[1])); return *this; } //------------------------------------------------------------------------ const trans_affine& trans_affine::rect_to_parl(double x1, double y1, double x2, double y2, const double* parl) { double src[6]; src[0] = x1; src[1] = y1; src[2] = x2; src[3] = y1; src[4] = x2; src[5] = y2; parl_to_parl(src, parl); return *this; } //------------------------------------------------------------------------ const trans_affine& trans_affine::parl_to_rect(const double* parl, double x1, double y1, double x2, double y2) { double dst[6]; dst[0] = x1; dst[1] = y1; dst[2] = x2; dst[3] = y1; dst[4] = x2; dst[5] = y2; parl_to_parl(parl, dst); return *this; } //------------------------------------------------------------------------ const trans_affine& trans_affine::multiply(const trans_affine& m) { double t0 = m0 * m.m0 + m1 * m.m2; double t2 = m2 * m.m0 + m3 * m.m2; double t4 = m4 * m.m0 + m5 * m.m2 + m.m4; m1 = m0 * m.m1 + m1 * m.m3; m3 = m2 * m.m1 + m3 * m.m3; m5 = m4 * m.m1 + m5 * m.m3 + m.m5; m0 = t0; m2 = t2; m4 = t4; return *this; } //------------------------------------------------------------------------ const trans_affine& trans_affine::invert() { double d = determinant(); double t0 = m3 * d; m3 = m0 * d; m1 = -m1 * d; m2 = -m2 * d; double t4 = -m4 * t0 - m5 * m2; m5 = -m4 * m1 - m5 * m3; m0 = t0; m4 = t4; return *this; } //------------------------------------------------------------------------ const trans_affine& trans_affine::flip_x() { m0 = -m0; m1 = -m1; m4 = -m4; return *this; } //------------------------------------------------------------------------ const trans_affine& trans_affine::flip_y() { m2 = -m2; m3 = -m3; m5 = -m5; return *this; } //------------------------------------------------------------------------ const trans_affine& trans_affine::reset() { m0 = m3 = 1.0; m1 = m2 = m4 = m5 = 0.0; return *this; } //------------------------------------------------------------------------ inline bool is_equal_eps(double v1, double v2, double epsilon) { return fabs(v1 - v2) < epsilon; } //------------------------------------------------------------------------ bool trans_affine::is_identity(double epsilon) const { return is_equal_eps(m0, 1.0, epsilon) && is_equal_eps(m1, 0.0, epsilon) && is_equal_eps(m2, 0.0, epsilon) && is_equal_eps(m3, 1.0, epsilon) && is_equal_eps(m4, 0.0, epsilon) && is_equal_eps(m5, 0.0, epsilon); } //------------------------------------------------------------------------ bool trans_affine::is_equal(const trans_affine& m, double epsilon) const { return is_equal_eps(m0, m.m0, epsilon) && is_equal_eps(m1, m.m1, epsilon) && is_equal_eps(m2, m.m2, epsilon) && is_equal_eps(m3, m.m3, epsilon) && is_equal_eps(m4, m.m4, epsilon) && is_equal_eps(m5, m.m5, epsilon); } //------------------------------------------------------------------------ double trans_affine::rotation() const { double x1 = 0.0; double y1 = 0.0; double x2 = 1.0; double y2 = 0.0; transform(&x1, &y1); transform(&x2, &y2); return atan2(y2-y1, x2-x1); } //------------------------------------------------------------------------ void trans_affine::translation(double* dx, double* dy) const { trans_affine t(*this); t *= trans_affine_rotation(-rotation()); t.transform(dx, dy); } //------------------------------------------------------------------------ void trans_affine::scaling(double* sx, double* sy) const { double x1 = 0.0; double y1 = 0.0; double x2 = 1.0; double y2 = 1.0; trans_affine t(*this); t *= trans_affine_rotation(-rotation()); t.transform(&x1, &y1); t.transform(&x2, &y2); *sx = x2 - x1; *sy = y2 - y1; } } aggdraw-1.3.14/agg2/src/agg_trans_double_path.cpp000066400000000000000000000177121417726601400216620ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #include "agg_math.h" #include "agg_trans_double_path.h" namespace agg { //------------------------------------------------------------------------ trans_double_path::trans_double_path() : m_kindex1(0.0), m_kindex2(0.0), m_base_length(0.0), m_base_height(1.0), m_status1(initial), m_status2(initial), m_preserve_x_scale(true) { } //------------------------------------------------------------------------ void trans_double_path::reset() { m_src_vertices1.remove_all(); m_src_vertices2.remove_all(); m_kindex1 = 0.0; m_kindex1 = 0.0; m_status1 = initial; m_status2 = initial; } //------------------------------------------------------------------------ void trans_double_path::move_to1(double x, double y) { if(m_status1 == initial) { m_src_vertices1.modify_last(vertex_dist(x, y)); m_status1 = making_path; } else { line_to1(x, y); } } //------------------------------------------------------------------------ void trans_double_path::line_to1(double x, double y) { if(m_status1 == making_path) { m_src_vertices1.add(vertex_dist(x, y)); } } //------------------------------------------------------------------------ void trans_double_path::move_to2(double x, double y) { if(m_status2 == initial) { m_src_vertices2.modify_last(vertex_dist(x, y)); m_status2 = making_path; } else { line_to2(x, y); } } //------------------------------------------------------------------------ void trans_double_path::line_to2(double x, double y) { if(m_status2 == making_path) { m_src_vertices2.add(vertex_dist(x, y)); } } //------------------------------------------------------------------------ double trans_double_path::finalize_path(vertex_storage& vertices) { unsigned i; double dist; double d; if(vertices.size() > 2) { if(vertices[vertices.size() - 2].dist * 10.0 < vertices[vertices.size() - 3].dist) { d = vertices[vertices.size() - 3].dist + vertices[vertices.size() - 2].dist; vertices[vertices.size() - 2] = vertices[vertices.size() - 1]; vertices.remove_last(); vertices[vertices.size() - 2].dist = d; } } dist = 0; vertices.close(false); for(i = 0; i < vertices.size(); i++) { vertex_dist& v = vertices[i]; d = v.dist; v.dist = dist; dist += d; } return (vertices.size() - 1) / dist; } //------------------------------------------------------------------------ void trans_double_path::finalize_paths() { if(m_status1 == making_path && m_src_vertices1.size() > 1 && m_status2 == making_path && m_src_vertices2.size() > 1) { m_kindex1 = finalize_path(m_src_vertices1); m_kindex2 = finalize_path(m_src_vertices2); m_status1 = ready; m_status2 = ready; } } //------------------------------------------------------------------------ double trans_double_path::total_length1() const { if(m_base_length >= 1e-10) return m_base_length; return (m_status1 == ready) ? m_src_vertices1[m_src_vertices1.size() - 1].dist : 0.0; } //------------------------------------------------------------------------ double trans_double_path::total_length2() const { if(m_base_length >= 1e-10) return m_base_length; return (m_status2 == ready) ? m_src_vertices2[m_src_vertices2.size() - 1].dist : 0.0; } //------------------------------------------------------------------------ void trans_double_path::transform1(const vertex_storage& vertices, double kindex, double kx, double *x, double* y) const { double x1 = 0.0; double y1 = 0.0; double dx = 1.0; double dy = 1.0; double d = 0.0; double dd = 1.0; *x *= kx; if(*x < 0.0) { // Extrapolation on the left //-------------------------- x1 = vertices[0].x; y1 = vertices[0].y; dx = vertices[1].x - x1; dy = vertices[1].y - y1; dd = vertices[1].dist - vertices[0].dist; d = *x; } else if(*x > vertices[vertices.size() - 1].dist) { // Extrapolation on the right //-------------------------- unsigned i = vertices.size() - 2; unsigned j = vertices.size() - 1; x1 = vertices[j].x; y1 = vertices[j].y; dx = x1 - vertices[i].x; dy = y1 - vertices[i].y; dd = vertices[j].dist - vertices[i].dist; d = *x - vertices[j].dist; } else { // Interpolation //-------------------------- unsigned i = 0; unsigned j = vertices.size() - 1; if(m_preserve_x_scale) { unsigned k; for(i = 0; (j - i) > 1; ) { if(*x < vertices[k = (i + j) >> 1].dist) { j = k; } else { i = k; } } d = vertices[i].dist; dd = vertices[j].dist - d; d = *x - d; } else { i = (unsigned)floor(*x * kindex); j = i + 1; dd = vertices[j].dist - vertices[i].dist; d = ((*x * kindex) - i) * dd; } x1 = vertices[i].x; y1 = vertices[i].y; dx = vertices[j].x - x1; dy = vertices[j].y - y1; } *x = x1 + dx * d / dd; *y = y1 + dy * d / dd; } //------------------------------------------------------------------------ void trans_double_path::transform(double *x, double *y) const { if(m_status1 == ready && m_status2 == ready) { if(m_base_length > 1e-10) { *x *= m_src_vertices1[m_src_vertices1.size() - 1].dist / m_base_length; } double x1 = *x; double y1 = *y; double x2 = *x; double y2 = *y; double dd = m_src_vertices2[m_src_vertices2.size() - 1].dist / m_src_vertices1[m_src_vertices1.size() - 1].dist; transform1(m_src_vertices1, m_kindex1, 1.0, &x1, &y1); transform1(m_src_vertices2, m_kindex2, dd, &x2, &y2); *x = x1 + *y * (x2 - x1) / m_base_height; *y = y1 + *y * (y2 - y1) / m_base_height; } } } aggdraw-1.3.14/agg2/src/agg_trans_single_path.cpp000066400000000000000000000146571417726601400216760ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #include "agg_math.h" #include "agg_vertex_sequence.h" #include "agg_trans_single_path.h" namespace agg { //------------------------------------------------------------------------ trans_single_path::trans_single_path() : m_base_length(0.0), m_kindex(0.0), m_status(initial), m_preserve_x_scale(true) { } //------------------------------------------------------------------------ void trans_single_path::reset() { m_src_vertices.remove_all(); m_kindex = 0.0; m_status = initial; } //------------------------------------------------------------------------ void trans_single_path::move_to(double x, double y) { if(m_status == initial) { m_src_vertices.modify_last(vertex_dist(x, y)); m_status = making_path; } else { line_to(x, y); } } //------------------------------------------------------------------------ void trans_single_path::line_to(double x, double y) { if(m_status == making_path) { m_src_vertices.add(vertex_dist(x, y)); } } //------------------------------------------------------------------------ void trans_single_path::finalize_path() { if(m_status == making_path && m_src_vertices.size() > 1) { unsigned i; double dist; double d; if(m_src_vertices.size() > 2) { if(m_src_vertices[m_src_vertices.size() - 2].dist * 10.0 < m_src_vertices[m_src_vertices.size() - 3].dist) { d = m_src_vertices[m_src_vertices.size() - 3].dist + m_src_vertices[m_src_vertices.size() - 2].dist; m_src_vertices[m_src_vertices.size() - 2] = m_src_vertices[m_src_vertices.size() - 1]; m_src_vertices.remove_last(); m_src_vertices[m_src_vertices.size() - 2].dist = d; } } dist = 0.0; m_src_vertices.close(false); for(i = 0; i < m_src_vertices.size(); i++) { vertex_dist& v = m_src_vertices[i]; double d = v.dist; v.dist = dist; dist += d; } m_kindex = (m_src_vertices.size() - 1) / dist; m_status = ready; } } //------------------------------------------------------------------------ double trans_single_path::total_length() const { if(m_base_length >= 1e-10) return m_base_length; return (m_status == ready) ? m_src_vertices[m_src_vertices.size() - 1].dist : 0.0; } //------------------------------------------------------------------------ void trans_single_path::transform(double *x, double *y) const { if(m_status == ready) { if(m_base_length > 1e-10) { *x *= m_src_vertices[m_src_vertices.size() - 1].dist / m_base_length; } double x1 = 0.0; double y1 = 0.0; double dx = 1.0; double dy = 1.0; double d = 0.0; double dd = 1.0; if(*x < 0.0) { // Extrapolation on the left //-------------------------- x1 = m_src_vertices[0].x; y1 = m_src_vertices[0].y; dx = m_src_vertices[1].x - x1; dy = m_src_vertices[1].y - y1; dd = m_src_vertices[1].dist - m_src_vertices[0].dist; d = *x; } else if(*x > m_src_vertices[m_src_vertices.size() - 1].dist) { // Extrapolation on the right //-------------------------- unsigned i = m_src_vertices.size() - 2; unsigned j = m_src_vertices.size() - 1; x1 = m_src_vertices[j].x; y1 = m_src_vertices[j].y; dx = x1 - m_src_vertices[i].x; dy = y1 - m_src_vertices[i].y; dd = m_src_vertices[j].dist - m_src_vertices[i].dist; d = *x - m_src_vertices[j].dist; } else { // Interpolation //-------------------------- unsigned i = 0; unsigned j = m_src_vertices.size() - 1; if(m_preserve_x_scale) { unsigned k; for(i = 0; (j - i) > 1; ) { if(*x < m_src_vertices[k = (i + j) >> 1].dist) { j = k; } else { i = k; } } d = m_src_vertices[i].dist; dd = m_src_vertices[j].dist - d; d = *x - d; } else { i = (unsigned)floor(*x * m_kindex); j = i + 1; dd = m_src_vertices[j].dist - m_src_vertices[i].dist; d = ((*x * m_kindex) - i) * dd; } x1 = m_src_vertices[i].x; y1 = m_src_vertices[i].y; dx = m_src_vertices[j].x - x1; dy = m_src_vertices[j].y - y1; } double x2 = x1 + dx * d / dd; double y2 = y1 + dy * d / dd; *x = x2 - *y * dy / dd; *y = y2 + *y * dx / dd; } } } aggdraw-1.3.14/agg2/src/agg_trans_warp_magnifier.cpp000066400000000000000000000031431417726601400223570ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #include #include "agg_trans_warp_magnifier.h" namespace agg { //------------------------------------------------------------------------ void trans_warp_magnifier::transform(double* x, double* y) const { double dx = *x - m_xc; double dy = *y - m_yc; double r = sqrt(dx * dx + dy * dy); if(r < m_radius) { *x = m_xc + dx * m_magn; *y = m_yc + dy * m_magn; return; } double m = (r + m_radius * (m_magn - 1.0)) / r; *x = m_xc + dx * m; *y = m_yc + dy * m; } //------------------------------------------------------------------------ void trans_warp_magnifier::inverse_transform(double* x, double* y) const { trans_warp_magnifier t(*this); t.magnification(1.0 / m_magn); t.radius(m_radius * m_magn); t.transform(x, y); } } aggdraw-1.3.14/agg2/src/agg_vcgen_bspline.cpp000066400000000000000000000147441417726601400210050ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #include "agg_vcgen_bspline.h" namespace agg { //------------------------------------------------------------------------ vcgen_bspline::vcgen_bspline() : m_src_vertices(), m_spline_x(), m_spline_y(), m_interpolation_step(1.0/50.0), m_closed(0), m_status(initial), m_src_vertex(0) { } //------------------------------------------------------------------------ void vcgen_bspline::remove_all() { m_src_vertices.remove_all(); m_closed = 0; m_status = initial; m_src_vertex = 0; } //------------------------------------------------------------------------ void vcgen_bspline::add_vertex(double x, double y, unsigned cmd) { m_status = initial; if(is_move_to(cmd)) { m_src_vertices.modify_last(point_type(x, y)); } else { if(is_vertex(cmd)) { m_src_vertices.add(point_type(x, y)); } else { m_closed = get_close_flag(cmd); } } } //------------------------------------------------------------------------ void vcgen_bspline::rewind(unsigned) { m_cur_abscissa = 0.0; m_max_abscissa = 0.0; m_src_vertex = 0; if(m_status == initial && m_src_vertices.size() > 2) { if(m_closed) { m_spline_x.init(m_src_vertices.size() + 8); m_spline_y.init(m_src_vertices.size() + 8); m_spline_x.add_point(0.0, m_src_vertices.prev(m_src_vertices.size() - 3).x); m_spline_y.add_point(0.0, m_src_vertices.prev(m_src_vertices.size() - 3).y); m_spline_x.add_point(1.0, m_src_vertices[m_src_vertices.size() - 3].x); m_spline_y.add_point(1.0, m_src_vertices[m_src_vertices.size() - 3].y); m_spline_x.add_point(2.0, m_src_vertices[m_src_vertices.size() - 2].x); m_spline_y.add_point(2.0, m_src_vertices[m_src_vertices.size() - 2].y); m_spline_x.add_point(3.0, m_src_vertices[m_src_vertices.size() - 1].x); m_spline_y.add_point(3.0, m_src_vertices[m_src_vertices.size() - 1].y); } else { m_spline_x.init(m_src_vertices.size()); m_spline_y.init(m_src_vertices.size()); } unsigned i; for(i = 0; i < m_src_vertices.size(); i++) { double x = m_closed ? i + 4 : i; m_spline_x.add_point(x, m_src_vertices[i].x); m_spline_y.add_point(x, m_src_vertices[i].y); } m_cur_abscissa = 0.0; m_max_abscissa = m_src_vertices.size() - 1; if(m_closed) { m_cur_abscissa = 4.0; m_max_abscissa += 5.0; m_spline_x.add_point(m_src_vertices.size() + 4, m_src_vertices[0].x); m_spline_y.add_point(m_src_vertices.size() + 4, m_src_vertices[0].y); m_spline_x.add_point(m_src_vertices.size() + 5, m_src_vertices[1].x); m_spline_y.add_point(m_src_vertices.size() + 5, m_src_vertices[1].y); m_spline_x.add_point(m_src_vertices.size() + 6, m_src_vertices[2].x); m_spline_y.add_point(m_src_vertices.size() + 6, m_src_vertices[2].y); m_spline_x.add_point(m_src_vertices.size() + 7, m_src_vertices.next(2).x); m_spline_y.add_point(m_src_vertices.size() + 7, m_src_vertices.next(2).y); } m_spline_x.prepare(); m_spline_y.prepare(); } } //------------------------------------------------------------------------ unsigned vcgen_bspline::vertex(double* x, double* y) { unsigned cmd = path_cmd_line_to; while(!is_stop(cmd)) { switch(m_status) { case initial: rewind(0); case ready: if(m_src_vertices.size() < 2) { cmd = path_cmd_stop; break; } if(m_src_vertices.size() == 2) { *x = m_src_vertices[m_src_vertex].x; *y = m_src_vertices[m_src_vertex].y; m_src_vertex++; if(m_src_vertex == 1) return path_cmd_move_to; if(m_src_vertex == 2) return path_cmd_line_to; cmd = path_cmd_stop; break; } cmd = path_cmd_move_to; m_status = polygon; m_src_vertex = 0; case polygon: if(m_cur_abscissa >= m_max_abscissa) { if(m_closed) { m_status = end_poly; break; } else { *x = m_src_vertices[m_src_vertices.size() - 1].x; *y = m_src_vertices[m_src_vertices.size() - 1].y; m_status = end_poly; return path_cmd_line_to; } } *x = m_spline_x.get_stateful(m_cur_abscissa); *y = m_spline_y.get_stateful(m_cur_abscissa); m_src_vertex++; m_cur_abscissa += m_interpolation_step; return (m_src_vertex == 1) ? path_cmd_move_to : path_cmd_line_to; case end_poly: m_status = stop; return path_cmd_end_poly | m_closed; case stop: return path_cmd_stop; } } return cmd; } } aggdraw-1.3.14/agg2/src/agg_vcgen_contour.cpp000066400000000000000000000145341417726601400210370ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Contour generator // //---------------------------------------------------------------------------- #include #include "agg_vcgen_contour.h" namespace agg { //------------------------------------------------------------------------ vcgen_contour::vcgen_contour() : m_src_vertices(), m_width(1.0), m_abs_width(1.0), m_signed_width(1.0), m_miter_limit(4.0), m_status(initial), m_src_vertex(0), m_closed(0), m_orientation(0), m_auto_detect(true) { } //------------------------------------------------------------------------ void vcgen_contour::remove_all() { m_src_vertices.remove_all(); m_closed = 0; m_orientation = 0; m_abs_width = fabs(m_width); m_signed_width = m_width; m_status = initial; } //------------------------------------------------------------------------ void vcgen_contour::miter_limit_theta(double t) { m_miter_limit = 1.0 / sin(t * 0.5) ; } //------------------------------------------------------------------------ void vcgen_contour::add_vertex(double x, double y, unsigned cmd) { m_status = initial; if(is_move_to(cmd)) { m_src_vertices.modify_last(vertex_dist(x, y)); } else { if(is_vertex(cmd)) { m_src_vertices.add(vertex_dist(x, y)); } else { if(is_end_poly(cmd)) { m_closed = get_close_flag(cmd); if(m_orientation == path_flags_none) { m_orientation = get_orientation(cmd); } } } } } //------------------------------------------------------------------------ void vcgen_contour::rewind(unsigned) { if(m_status == initial) { m_src_vertices.close(true); m_signed_width = m_width; if(m_auto_detect) { if(!is_oriented(m_orientation)) { m_orientation = (calc_polygon_area(m_src_vertices) > 0.0) ? path_flags_ccw : path_flags_cw; } } if(is_oriented(m_orientation)) { m_signed_width = is_ccw(m_orientation) ? m_width : -m_width; } } m_status = ready; m_src_vertex = 0; } //------------------------------------------------------------------------ unsigned vcgen_contour::vertex(double* x, double* y) { bool done = false; while(!done) { switch(m_status) { case initial: rewind(0); case ready: if(m_src_vertices.size() < 3) { return path_cmd_stop; } m_src_vertex = 0; m_status = outline; case outline: if(m_src_vertex >= m_src_vertices.size()) { m_status = end_poly; return path_cmd_end_poly | m_orientation | m_closed; } if(calc_miter(m_src_vertices.prev(m_src_vertex), m_src_vertices.curr(m_src_vertex), m_src_vertices.next(m_src_vertex))) { m_status = add_point; } ++m_src_vertex; *x = m_x1; *y = m_y1; return ((m_src_vertex == 1) ? path_cmd_move_to : path_cmd_line_to); case add_point: *x = m_x2; *y = m_y2; m_status = outline; return path_cmd_line_to; case end_poly: done = true; break; } } return path_cmd_stop; } //------------------------------------------------------------------------ bool vcgen_contour::calc_miter(const vertex_dist& v0, const vertex_dist& v1, const vertex_dist& v2) { double dx1, dy1, dx2, dy2; dx1 = m_signed_width * (v1.y - v0.y) / v0.dist; dy1 = m_signed_width * (v1.x - v0.x) / v0.dist; dx2 = m_signed_width * (v2.y - v1.y) / v1.dist; dy2 = m_signed_width * (v2.x - v1.x) / v1.dist; double xi; double yi; if(!calc_intersection(v0.x + dx1, v0.y - dy1, v1.x + dx1, v1.y - dy1, v1.x + dx2, v1.y - dy2, v2.x + dx2, v2.y - dy2, &xi, &yi)) { m_x1 = v1.x + dx1; m_y1 = v1.y - dy1; return false; } else { double d1 = calc_distance(v1.x, v1.y, xi, yi); double lim = m_abs_width * m_miter_limit; if(d1 > lim) { d1 = lim / d1; m_x1 = v1.x + dx1; m_y1 = v1.y - dy1; m_x2 = v1.x + dx2; m_y2 = v1.y - dy2; m_x1 += (xi - m_x1) * d1; m_y1 += (yi - m_y1) * d1; m_x2 += (xi - m_x2) * d1; m_y2 += (yi - m_y2) * d1; return true; } else { m_x1 = xi; m_y1 = yi; } } return false; } } aggdraw-1.3.14/agg2/src/agg_vcgen_dash.cpp000066400000000000000000000156411417726601400202650ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Line dash generator // //---------------------------------------------------------------------------- #include #include "agg_vcgen_dash.h" #include "agg_shorten_path.h" namespace agg { //------------------------------------------------------------------------ vcgen_dash::vcgen_dash() : m_total_dash_len(0.0), m_num_dashes(0), m_dash_start(0.0), m_shorten(0.0), m_curr_dash_start(0.0), m_curr_dash(0), m_src_vertices(), m_closed(0), m_status(initial), m_src_vertex(0) { } //------------------------------------------------------------------------ void vcgen_dash::remove_all_dashes() { m_total_dash_len = 0.0; m_num_dashes = 0; m_curr_dash_start = 0.0; m_curr_dash = 0; } //------------------------------------------------------------------------ void vcgen_dash::add_dash(double dash_len, double gap_len) { if(m_num_dashes < max_dashes) { m_total_dash_len += dash_len + gap_len; m_dashes[m_num_dashes++] = dash_len; m_dashes[m_num_dashes++] = gap_len; } } //------------------------------------------------------------------------ void vcgen_dash::dash_start(double ds) { m_dash_start = ds; calc_dash_start(fabs(ds)); } //------------------------------------------------------------------------ void vcgen_dash::calc_dash_start(double ds) { m_curr_dash = 0; m_curr_dash_start = 0.0; while(ds > 0.0) { if(ds > m_dashes[m_curr_dash]) { ds -= m_dashes[m_curr_dash]; ++m_curr_dash; m_curr_dash_start = 0.0; if(m_curr_dash >= m_num_dashes) m_curr_dash = 0; } else { m_curr_dash_start = ds; ds = 0.0; } } } //------------------------------------------------------------------------ void vcgen_dash::remove_all() { m_status = initial; m_src_vertices.remove_all(); m_closed = 0; } //------------------------------------------------------------------------ void vcgen_dash::add_vertex(double x, double y, unsigned cmd) { m_status = initial; if(is_move_to(cmd)) { m_src_vertices.modify_last(vertex_dist(x, y)); } else { if(is_vertex(cmd)) { m_src_vertices.add(vertex_dist(x, y)); } else { m_closed = get_close_flag(cmd); } } } //------------------------------------------------------------------------ void vcgen_dash::rewind(unsigned) { if(m_status == initial) { m_src_vertices.close(m_closed != 0); shorten_path(m_src_vertices, m_shorten, m_closed); } m_status = ready; m_src_vertex = 0; } //------------------------------------------------------------------------ unsigned vcgen_dash::vertex(double* x, double* y) { unsigned cmd = path_cmd_move_to; while(!is_stop(cmd)) { switch(m_status) { case initial: rewind(0); case ready: if(m_num_dashes < 2 || m_src_vertices.size() < 2) { cmd = path_cmd_stop; break; } m_status = polyline; m_src_vertex = 1; m_v1 = &m_src_vertices[0]; m_v2 = &m_src_vertices[1]; m_curr_rest = m_v1->dist; *x = m_v1->x; *y = m_v1->y; if(m_dash_start >= 0.0) calc_dash_start(m_dash_start); return path_cmd_move_to; case polyline: { double dash_rest = m_dashes[m_curr_dash] - m_curr_dash_start; unsigned cmd = (m_curr_dash & 1) ? path_cmd_move_to : path_cmd_line_to; if(m_curr_rest > dash_rest) { m_curr_rest -= dash_rest; ++m_curr_dash; if(m_curr_dash >= m_num_dashes) m_curr_dash = 0; m_curr_dash_start = 0.0; *x = m_v2->x - (m_v2->x - m_v1->x) * m_curr_rest / m_v1->dist; *y = m_v2->y - (m_v2->y - m_v1->y) * m_curr_rest / m_v1->dist; } else { m_curr_dash_start += m_curr_rest; *x = m_v2->x; *y = m_v2->y; ++m_src_vertex; m_v1 = m_v2; m_curr_rest = m_v1->dist; if(m_closed) { if(m_src_vertex > m_src_vertices.size()) { m_status = stop; } else { m_v2 = &m_src_vertices [ (m_src_vertex >= m_src_vertices.size()) ? 0 : m_src_vertex ]; } } else { if(m_src_vertex >= m_src_vertices.size()) { m_status = stop; } else { m_v2 = &m_src_vertices[m_src_vertex]; } } } return cmd; } break; case stop: cmd = path_cmd_stop; break; } } return path_cmd_stop; } } aggdraw-1.3.14/agg2/src/agg_vcgen_markers_term.cpp000066400000000000000000000063321417726601400220360ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Terminal markers generator (arrowhead/arrowtail) // //---------------------------------------------------------------------------- #include "agg_vcgen_markers_term.h" namespace agg { //------------------------------------------------------------------------ void vcgen_markers_term::remove_all() { m_markers.remove_all(); } //------------------------------------------------------------------------ void vcgen_markers_term::add_vertex(double x, double y, unsigned cmd) { if(is_move_to(cmd)) { if(m_markers.size() & 1) { // Initial state, the first coordinate was added. // If two of more calls of start_vertex() occures // we just modify the last one. m_markers.modify_last(coord_type(x, y)); } else { m_markers.add(coord_type(x, y)); } } else { if(is_vertex(cmd)) { if(m_markers.size() & 1) { // Initial state, the first coordinate was added. // Add three more points, 0,1,1,0 m_markers.add(coord_type(x, y)); m_markers.add(m_markers[m_markers.size() - 1]); m_markers.add(m_markers[m_markers.size() - 3]); } else { if(m_markers.size()) { // Replace two last points: 0,1,1,0 -> 0,1,2,1 m_markers[m_markers.size() - 1] = m_markers[m_markers.size() - 2]; m_markers[m_markers.size() - 2] = coord_type(x, y); } } } } } //------------------------------------------------------------------------ void vcgen_markers_term::rewind(unsigned id) { m_curr_id = id * 2; m_curr_idx = m_curr_id; } //------------------------------------------------------------------------ unsigned vcgen_markers_term::vertex(double* x, double* y) { if(m_curr_id > 2 || m_curr_idx >= m_markers.size()) { return path_cmd_stop; } const coord_type& c = m_markers[m_curr_idx]; *x = c.x; *y = c.y; if(m_curr_idx & 1) { m_curr_idx += 3; return path_cmd_line_to; } ++m_curr_idx; return path_cmd_move_to; } } aggdraw-1.3.14/agg2/src/agg_vcgen_smooth_poly1.cpp000066400000000000000000000155401417726601400220010ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Smooth polygon generator // //---------------------------------------------------------------------------- #include "agg_vcgen_smooth_poly1.h" namespace agg { //------------------------------------------------------------------------ vcgen_smooth_poly1::vcgen_smooth_poly1() : m_src_vertices(), m_smooth_value(0.5), m_closed(0), m_status(initial), m_src_vertex(0) { } //------------------------------------------------------------------------ void vcgen_smooth_poly1::remove_all() { m_src_vertices.remove_all(); m_closed = 0; m_status = initial; } //------------------------------------------------------------------------ void vcgen_smooth_poly1::add_vertex(double x, double y, unsigned cmd) { m_status = initial; if(is_move_to(cmd)) { m_src_vertices.modify_last(vertex_dist(x, y)); } else { if(is_vertex(cmd)) { m_src_vertices.add(vertex_dist(x, y)); } else { m_closed = get_close_flag(cmd); } } } //------------------------------------------------------------------------ void vcgen_smooth_poly1::rewind(unsigned) { if(m_status == initial) { m_src_vertices.close(m_closed != 0); } m_status = ready; m_src_vertex = 0; } //------------------------------------------------------------------------ void vcgen_smooth_poly1::calculate(const vertex_dist& v0, const vertex_dist& v1, const vertex_dist& v2, const vertex_dist& v3) { double k1 = v0.dist / (v0.dist + v1.dist); double k2 = v1.dist / (v1.dist + v2.dist); double xm1 = v0.x + (v2.x - v0.x) * k1; double ym1 = v0.y + (v2.y - v0.y) * k1; double xm2 = v1.x + (v3.x - v1.x) * k2; double ym2 = v1.y + (v3.y - v1.y) * k2; m_ctrl1_x = v1.x + m_smooth_value * (v2.x - xm1); m_ctrl1_y = v1.y + m_smooth_value * (v2.y - ym1); m_ctrl2_x = v2.x + m_smooth_value * (v1.x - xm2); m_ctrl2_y = v2.y + m_smooth_value * (v1.y - ym2); } //------------------------------------------------------------------------ unsigned vcgen_smooth_poly1::vertex(double* x, double* y) { unsigned cmd = path_cmd_line_to; while(!is_stop(cmd)) { switch(m_status) { case initial: rewind(0); case ready: if(m_src_vertices.size() < 2) { cmd = path_cmd_stop; break; } if(m_src_vertices.size() == 2) { *x = m_src_vertices[m_src_vertex].x; *y = m_src_vertices[m_src_vertex].y; m_src_vertex++; if(m_src_vertex == 1) return path_cmd_move_to; if(m_src_vertex == 2) return path_cmd_line_to; cmd = path_cmd_stop; break; } cmd = path_cmd_move_to; m_status = polygon; m_src_vertex = 0; case polygon: if(m_closed) { if(m_src_vertex >= m_src_vertices.size()) { *x = m_src_vertices[0].x; *y = m_src_vertices[0].y; m_status = end_poly; return path_cmd_curve4; } } else { if(m_src_vertex >= m_src_vertices.size() - 1) { *x = m_src_vertices[m_src_vertices.size() - 1].x; *y = m_src_vertices[m_src_vertices.size() - 1].y; m_status = end_poly; return path_cmd_curve3; } } calculate(m_src_vertices.prev(m_src_vertex), m_src_vertices.curr(m_src_vertex), m_src_vertices.next(m_src_vertex), m_src_vertices.next(m_src_vertex + 1)); *x = m_src_vertices[m_src_vertex].x; *y = m_src_vertices[m_src_vertex].y; m_src_vertex++; if(m_closed) { m_status = ctrl1; return ((m_src_vertex == 1) ? path_cmd_move_to : path_cmd_curve4); } else { if(m_src_vertex == 1) { m_status = ctrl_b; return path_cmd_move_to; } if(m_src_vertex >= m_src_vertices.size() - 1) { m_status = ctrl_e; return path_cmd_curve3; } m_status = ctrl1; return path_cmd_curve4; } break; case ctrl_b: *x = m_ctrl2_x; *y = m_ctrl2_y; m_status = polygon; return path_cmd_curve3; case ctrl_e: *x = m_ctrl1_x; *y = m_ctrl1_y; m_status = polygon; return path_cmd_curve3; case ctrl1: *x = m_ctrl1_x; *y = m_ctrl1_y; m_status = ctrl2; return path_cmd_curve4; case ctrl2: *x = m_ctrl2_x; *y = m_ctrl2_y; m_status = polygon; return path_cmd_curve4; case end_poly: m_status = stop; return path_cmd_end_poly | m_closed; case stop: return path_cmd_stop; } } return cmd; } } aggdraw-1.3.14/agg2/src/agg_vcgen_stroke.cpp000066400000000000000000000321751417726601400206560ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Stroke generator // //---------------------------------------------------------------------------- #include #include "agg_vcgen_stroke.h" #include "agg_shorten_path.h" namespace agg { //------------------------------------------------------------------------ vcgen_stroke::vcgen_stroke() : m_src_vertices(), m_out_vertices(), m_width(0.5), m_miter_limit(4.0), m_approx_scale(1.0), m_shorten(0.0), m_line_cap(butt_cap), m_line_join(miter_join), m_closed(0), m_status(initial), m_src_vertex(0), m_out_vertex(0) { } //------------------------------------------------------------------------ void vcgen_stroke::miter_limit_theta(double t) { m_miter_limit = 1.0 / sin(t * 0.5) ; } //------------------------------------------------------------------------ void vcgen_stroke::remove_all() { m_src_vertices.remove_all(); m_closed = 0; m_status = initial; } //------------------------------------------------------------------------ void vcgen_stroke::add_vertex(double x, double y, unsigned cmd) { m_status = initial; if(is_move_to(cmd)) { m_src_vertices.modify_last(vertex_dist(x, y)); } else { if(is_vertex(cmd)) { m_src_vertices.add(vertex_dist(x, y)); } else { m_closed = get_close_flag(cmd); } } } //------------------------------------------------------------------------ void vcgen_stroke::rewind(unsigned) { if(m_status == initial) { m_src_vertices.close(m_closed != 0); shorten_path(m_src_vertices, m_shorten, m_closed); } m_status = ready; m_src_vertex = 0; m_out_vertex = 0; } //------------------------------------------------------------------------ unsigned vcgen_stroke::vertex(double* x, double* y) { unsigned cmd = path_cmd_line_to; while(!is_stop(cmd)) { switch(m_status) { case initial: rewind(0); case ready: if(m_src_vertices.size() < 2 + unsigned(m_closed != 0)) { cmd = path_cmd_stop; break; } m_status = m_closed ? outline1 : cap1; cmd = path_cmd_move_to; m_src_vertex = 0; m_out_vertex = 0; break; case cap1: calc_cap(m_src_vertices[0], m_src_vertices[1], m_src_vertices[0].dist); m_src_vertex = 1; m_prev_status = outline1; m_status = out_vertices; m_out_vertex = 0; break; case cap2: calc_cap(m_src_vertices[m_src_vertices.size() - 1], m_src_vertices[m_src_vertices.size() - 2], m_src_vertices[m_src_vertices.size() - 2].dist); m_prev_status = outline2; m_status = out_vertices; m_out_vertex = 0; break; case outline1: if(m_closed) { if(m_src_vertex >= m_src_vertices.size()) { m_prev_status = close_first; m_status = end_poly1; break; } } else { if(m_src_vertex >= m_src_vertices.size() - 1) { m_status = cap2; break; } } calc_join(m_src_vertices.prev(m_src_vertex), m_src_vertices.curr(m_src_vertex), m_src_vertices.next(m_src_vertex), m_src_vertices.prev(m_src_vertex).dist, m_src_vertices.curr(m_src_vertex).dist); ++m_src_vertex; m_prev_status = m_status; m_status = out_vertices; m_out_vertex = 0; break; case close_first: m_status = outline2; cmd = path_cmd_move_to; case outline2: if(m_src_vertex <= unsigned(m_closed == 0)) { m_status = end_poly2; m_prev_status = stop; break; } --m_src_vertex; calc_join(m_src_vertices.next(m_src_vertex), m_src_vertices.curr(m_src_vertex), m_src_vertices.prev(m_src_vertex), m_src_vertices.curr(m_src_vertex).dist, m_src_vertices.prev(m_src_vertex).dist); m_prev_status = m_status; m_status = out_vertices; m_out_vertex = 0; break; case out_vertices: if(m_out_vertex >= m_out_vertices.size()) { m_status = m_prev_status; } else { const coord_type& c = m_out_vertices[m_out_vertex++]; *x = c.x; *y = c.y; return cmd; } break; case end_poly1: m_status = m_prev_status; return path_cmd_end_poly | path_flags_close | path_flags_ccw; case end_poly2: m_status = m_prev_status; return path_cmd_end_poly | path_flags_close | path_flags_cw; case stop: cmd = path_cmd_stop; break; } } return cmd; } //------------------------------------------------------------------------ void vcgen_stroke::calc_arc(double x, double y, double dx1, double dy1, double dx2, double dy2) { double a1 = atan2(dy1, dx1); double a2 = atan2(dy2, dx2); double da = a1 - a2; if(fabs(da) < vcgen_stroke_theta) { m_out_vertices.add(coord_type(x + dx1, y + dy1)); m_out_vertices.add(coord_type(x + dx2, y + dy2)); return; } bool ccw = da > 0.0 && da < pi; da = fabs(1.0 / (m_width * m_approx_scale)); if(!ccw) { if(a1 > a2) a2 += 2 * pi; while(a1 < a2) { m_out_vertices.add(coord_type(x + cos(a1) * m_width, y + sin(a1) * m_width)); a1 += da; } } else { if(a1 < a2) a2 -= 2 * pi; while(a1 > a2) { m_out_vertices.add(coord_type(x + cos(a1) * m_width, y + sin(a1) * m_width)); a1 -= da; } } m_out_vertices.add(coord_type(x + dx2, y + dy2)); } //------------------------------------------------------------------------ void vcgen_stroke::calc_cap(const vertex_dist& v0, const vertex_dist& v1, double len) { m_out_vertices.remove_all(); double dx1 = m_width * (v1.y - v0.y) / len; double dy1 = m_width * (v1.x - v0.x) / len; double dx2 = 0; double dy2 = 0; if(m_line_cap == square_cap) { dx2 = dy1; dy2 = dx1; } if(m_line_cap == round_cap) { double a1 = atan2(dy1, -dx1); double a2 = a1 + pi; double da = fabs(1.0 / (m_width * m_approx_scale)); while(a1 < a2) { m_out_vertices.add(coord_type(v0.x + cos(a1) * m_width, v0.y + sin(a1) * m_width)); a1 += da; } m_out_vertices.add(coord_type(v0.x + dx1, v0.y - dy1)); } else { m_out_vertices.add(coord_type(v0.x - dx1 - dx2, v0.y + dy1 - dy2)); m_out_vertices.add(coord_type(v0.x + dx1 - dx2, v0.y - dy1 - dy2)); } } //------------------------------------------------------------------------ void vcgen_stroke::calc_miter(const vertex_dist& v0, const vertex_dist& v1, const vertex_dist& v2, double dx1, double dy1, double dx2, double dy2, bool revert_flag) { double xi = v1.x; double yi = v1.y; if(!calc_intersection(v0.x + dx1, v0.y - dy1, v1.x + dx1, v1.y - dy1, v1.x + dx2, v1.y - dy2, v2.x + dx2, v2.y - dy2, &xi, &yi)) { // The calculation didn't succeed, most probaly // the the three points lie one straight line //---------------- m_out_vertices.add(coord_type(v1.x + dx1, v1.y - dy1)); } else { double d1 = calc_distance(v1.x, v1.y, xi, yi); double lim = m_width * m_miter_limit; if(d1 > lim) { // Miter limit exceeded //------------------------ if(revert_flag) { // For the compatibility with SVG, PDF, etc, // we use a simple bevel join instead of // "smart" bevel //------------------- m_out_vertices.add(coord_type(v1.x + dx1, v1.y - dy1)); m_out_vertices.add(coord_type(v1.x + dx2, v1.y - dy2)); } else { // Smart bevel that cuts the miter at the limit point //------------------- d1 = lim / d1; double x1 = v1.x + dx1; double y1 = v1.y - dy1; double x2 = v1.x + dx2; double y2 = v1.y - dy2; x1 += (xi - x1) * d1; y1 += (yi - y1) * d1; x2 += (xi - x2) * d1; y2 += (yi - y2) * d1; m_out_vertices.add(coord_type(x1, y1)); m_out_vertices.add(coord_type(x2, y2)); } } else { // Inside the miter limit //--------------------- m_out_vertices.add(coord_type(xi, yi)); } } } //------------------------------------------------------------------------ void vcgen_stroke::calc_join(const vertex_dist& v0, const vertex_dist& v1, const vertex_dist& v2, double len1, double len2) { double dx1, dy1, dx2, dy2; dx1 = m_width * (v1.y - v0.y) / len1; dy1 = m_width * (v1.x - v0.x) / len1; dx2 = m_width * (v2.y - v1.y) / len2; dy2 = m_width * (v2.x - v1.x) / len2; m_out_vertices.remove_all(); if(m_line_join == miter_join) { calc_miter(v0, v1, v2, dx1, dy1, dx2, dy2, m_line_join == miter_join_revert); } else { if(calc_point_location(v0.x, v0.y, v1.x, v1.y, v2.x, v2.y) > 0.0) { calc_miter(v0, v1, v2, dx1, dy1, dx2, dy2, false); } else { if(m_line_join == round_join) { calc_arc(v1.x, v1.y, dx1, -dy1, dx2, -dy2); } else { if(m_line_join == miter_join_revert) { calc_miter(v0, v1, v2, dx1, dy1, dx2, dy2, true); } else { m_out_vertices.add(coord_type(v1.x + dx1, v1.y - dy1)); m_out_vertices.add(coord_type(v1.x + dx2, v1.y - dy2)); } } } } } } aggdraw-1.3.14/agg2/src/agg_vpgen_clip_polygon.cpp000066400000000000000000000072431417726601400220600ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #include "agg_vpgen_clip_polygon.h" #include "agg_clip_liang_barsky.h" namespace agg { //------------------------------------------------------------------------ // Determine the clipping code of the vertex according to the // Cyrus-Beck line clipping algorithm // // | | // 0110 | 0010 | 0011 // | | // -------+--------+-------- clip_box.y2 // | | // 0100 | 0000 | 0001 // | | // -------+--------+-------- clip_box.y1 // | | // 1100 | 1000 | 1001 // | | // clip_box.x1 clip_box.x2 // // unsigned vpgen_clip_polygon::clipping_flags(double x, double y) { if(x < m_clip_box.x1) { if(y > m_clip_box.y2) return 6; if(y < m_clip_box.y1) return 12; return 4; } if(x > m_clip_box.x2) { if(y > m_clip_box.y2) return 3; if(y < m_clip_box.y1) return 9; return 1; } if(y > m_clip_box.y2) return 2; if(y < m_clip_box.y1) return 8; return 0; } //---------------------------------------------------------------------------- void vpgen_clip_polygon::reset() { m_vertex = 0; m_num_vertices = 0; } //---------------------------------------------------------------------------- void vpgen_clip_polygon::move_to(double x, double y) { m_vertex = 0; m_num_vertices = 0; m_clip_flags = clipping_flags(x, y); if(m_clip_flags == 0) { m_x[0] = x; m_y[0] = y; m_num_vertices = 1; } m_x1 = x; m_y1 = y; m_cmd = path_cmd_move_to; } //---------------------------------------------------------------------------- void vpgen_clip_polygon::line_to(double x, double y) { m_vertex = 0; m_num_vertices = 0; unsigned flags = clipping_flags(x, y); if(m_clip_flags == flags) { if(flags == 0) { m_x[0] = x; m_y[0] = y; m_num_vertices = 1; } } else { m_num_vertices = clip_liang_barsky(m_x1, m_y1, x, y, m_clip_box, m_x, m_y); } m_clip_flags = flags; m_x1 = x; m_y1 = y; } //---------------------------------------------------------------------------- unsigned vpgen_clip_polygon::vertex(double* x, double* y) { if(m_vertex < m_num_vertices) { *x = m_x[m_vertex]; *y = m_y[m_vertex]; ++m_vertex; unsigned cmd = m_cmd; m_cmd = path_cmd_line_to; return cmd; } return path_cmd_stop; } } aggdraw-1.3.14/agg2/src/agg_vpgen_segmentator.cpp000066400000000000000000000034531417726601400217110ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- #include #include "agg_vpgen_segmentator.h" namespace agg { void vpgen_segmentator::move_to(double x, double y) { m_x1 = x; m_y1 = y; m_dx = 0.0; m_dy = 0.0; m_dl = 2.0; m_cmd = path_cmd_move_to; } void vpgen_segmentator::line_to(double x, double y) { m_x1 += m_dx; m_y1 += m_dy; m_dx = x - m_x1; m_dy = y - m_y1; double len = sqrt(m_dx * m_dx + m_dy * m_dy) * m_approximation_scale; if(len < 1e-30) len = 1e-30; m_ddl = 1.0 / len; m_dl = (m_cmd == path_cmd_move_to) ? 0.0 : m_ddl; if(m_cmd == path_cmd_stop) m_cmd = path_cmd_line_to; } unsigned vpgen_segmentator::vertex(double* x, double* y) { if(m_cmd == path_cmd_stop) return path_cmd_stop; unsigned cmd = m_cmd; m_cmd = path_cmd_line_to; if(m_dl > 1.0) { m_dl = 1.0; m_cmd = path_cmd_stop; } *x = m_x1 + m_dx * m_dl; *y = m_y1 + m_dy * m_dl; m_dl += m_ddl; return cmd; } } aggdraw-1.3.14/agg2/src/ctrl/000077500000000000000000000000001417726601400155775ustar00rootroot00000000000000aggdraw-1.3.14/agg2/src/ctrl/agg_cbox_ctrl.cpp000066400000000000000000000142731417726601400211070ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // classes rbox_ctrl_impl, rbox_ctrl // //---------------------------------------------------------------------------- #include #include "ctrl/agg_cbox_ctrl.h" namespace agg { //------------------------------------------------------------------------ cbox_ctrl_impl::cbox_ctrl_impl(double x, double y, const char* l, bool flip_y) : ctrl(x, y, x + 9.0 * 1.5, y + 9.0 * 1.5, flip_y), m_text_thickness(1.5), m_text_height(9.0), m_text_width(0.0), m_status(false), m_text_poly(m_text) { label(l); } //------------------------------------------------------------------------ void cbox_ctrl_impl::text_size(double h, double w) { m_text_width = w; m_text_height = h; } //------------------------------------------------------------------------ void cbox_ctrl_impl::label(const char* l) { unsigned len = strlen(l); if(len > 127) len = 127; memcpy(m_label, l, len); m_label[len] = 0; } //------------------------------------------------------------------------ bool cbox_ctrl_impl::on_mouse_button_down(double x, double y) { inverse_transform_xy(&x, &y); if(x >= m_x1 && y >= m_y1 && x <= m_x2 && y <= m_y2) { m_status = !m_status; return true; } return false; } //------------------------------------------------------------------------ bool cbox_ctrl_impl::on_mouse_move(double, double, bool) { return false; } //------------------------------------------------------------------------ bool cbox_ctrl_impl::in_rect(double x, double y) const { inverse_transform_xy(&x, &y); return x >= m_x1 && y >= m_y1 && x <= m_x2 && y <= m_y2; } //------------------------------------------------------------------------ bool cbox_ctrl_impl::on_mouse_button_up(double, double) { return false; } //------------------------------------------------------------------------ bool cbox_ctrl_impl::on_arrow_keys(bool, bool, bool, bool) { return false; } //------------------------------------------------------------------------ void cbox_ctrl_impl::rewind(unsigned idx) { m_idx = idx; double d2; double t; switch(idx) { default: case 0: // Border m_vertex = 0; m_vx[0] = m_x1; m_vy[0] = m_y1; m_vx[1] = m_x2; m_vy[1] = m_y1; m_vx[2] = m_x2; m_vy[2] = m_y2; m_vx[3] = m_x1; m_vy[3] = m_y2; m_vx[4] = m_x1 + m_text_thickness; m_vy[4] = m_y1 + m_text_thickness; m_vx[5] = m_x1 + m_text_thickness; m_vy[5] = m_y2 - m_text_thickness; m_vx[6] = m_x2 - m_text_thickness; m_vy[6] = m_y2 - m_text_thickness; m_vx[7] = m_x2 - m_text_thickness; m_vy[7] = m_y1 + m_text_thickness; break; case 1: // Text m_text.text(m_label); m_text.start_point(m_x1 + m_text_height * 2.0, m_y1 + m_text_height / 5.0); m_text.size(m_text_height, m_text_width); m_text_poly.width(m_text_thickness); m_text_poly.line_join(vcgen_stroke::round_join); m_text_poly.line_cap(vcgen_stroke::round_cap); m_text_poly.rewind(0); break; case 2: // Active item m_vertex = 0; d2 = (m_y2 - m_y1) / 2.0; t = m_text_thickness * 1.5; m_vx[0] = m_x1 + m_text_thickness; m_vy[0] = m_y1 + m_text_thickness; m_vx[1] = m_x1 + d2; m_vy[1] = m_y1 + d2 - t; m_vx[2] = m_x2 - m_text_thickness; m_vy[2] = m_y1 + m_text_thickness; m_vx[3] = m_x1 + d2 + t; m_vy[3] = m_y1 + d2; m_vx[4] = m_x2 - m_text_thickness; m_vy[4] = m_y2 - m_text_thickness; m_vx[5] = m_x1 + d2; m_vy[5] = m_y1 + d2 + t; m_vx[6] = m_x1 + m_text_thickness; m_vy[6] = m_y2 - m_text_thickness; m_vx[7] = m_x1 + d2 - t; m_vy[7] = m_y1 + d2; break; } } //------------------------------------------------------------------------ unsigned cbox_ctrl_impl::vertex(double* x, double* y) { unsigned cmd = path_cmd_line_to; switch(m_idx) { case 0: if(m_vertex == 0 || m_vertex == 4) cmd = path_cmd_move_to; if(m_vertex >= 8) cmd = path_cmd_stop; *x = m_vx[m_vertex]; *y = m_vy[m_vertex]; m_vertex++; break; case 1: cmd = m_text_poly.vertex(x, y); break; case 2: if(m_status) { if(m_vertex == 0) cmd = path_cmd_move_to; if(m_vertex >= 8) cmd = path_cmd_stop; *x = m_vx[m_vertex]; *y = m_vy[m_vertex]; m_vertex++; } else { cmd = path_cmd_stop; } break; default: cmd = path_cmd_stop; break; } if(!is_stop(cmd)) { transform_xy(x, y); } return cmd; } } aggdraw-1.3.14/agg2/src/ctrl/agg_gamma_ctrl.cpp000066400000000000000000000324751417726601400212420ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // class gamma_ctrl_impl // //---------------------------------------------------------------------------- #include #include "agg_math.h" #include "ctrl/agg_gamma_ctrl.h" namespace agg { //------------------------------------------------------------------------ gamma_ctrl_impl::gamma_ctrl_impl(double x1, double y1, double x2, double y2, bool flip_y) : ctrl(x1, y1, x2, y2, flip_y), m_border_width(2.0), m_border_extra(0.0), m_curve_width(2.0), m_grid_width(0.2), m_text_thickness(1.5), m_point_size(5.0), m_text_height(9.0), m_text_width(0.0), m_xc1(x1), m_yc1(y1), m_xc2(x2), m_yc2(y2 - m_text_height * 2.0), m_xt1(x1), m_yt1(y2 - m_text_height * 2.0), m_xt2(x2), m_yt2(y2), m_curve_poly(m_gamma_spline), m_text_poly(m_text), m_idx(0), m_vertex(0), m_p1_active(true), m_mouse_point(0), m_pdx(0.0), m_pdy(0.0) { calc_spline_box(); } //------------------------------------------------------------------------ void gamma_ctrl_impl::calc_spline_box() { m_xs1 = m_xc1 + m_border_width; m_ys1 = m_yc1 + m_border_width; m_xs2 = m_xc2 - m_border_width; m_ys2 = m_yc2 - m_border_width * 0.5; } //------------------------------------------------------------------------ void gamma_ctrl_impl::calc_points() { double kx1, ky1, kx2, ky2; m_gamma_spline.values(&kx1, &ky1, &kx2, &ky2); m_xp1 = m_xs1 + (m_xs2 - m_xs1) * kx1 * 0.25; m_yp1 = m_ys1 + (m_ys2 - m_ys1) * ky1 * 0.25; m_xp2 = m_xs2 - (m_xs2 - m_xs1) * kx2 * 0.25; m_yp2 = m_ys2 - (m_ys2 - m_ys1) * ky2 * 0.25; } //------------------------------------------------------------------------ void gamma_ctrl_impl::calc_values() { double kx1, ky1, kx2, ky2; kx1 = (m_xp1 - m_xs1) * 4.0 / (m_xs2 - m_xs1); ky1 = (m_yp1 - m_ys1) * 4.0 / (m_ys2 - m_ys1); kx2 = (m_xs2 - m_xp2) * 4.0 / (m_xs2 - m_xs1); ky2 = (m_ys2 - m_yp2) * 4.0 / (m_ys2 - m_ys1); m_gamma_spline.values(kx1, ky1, kx2, ky2); } //------------------------------------------------------------------------ void gamma_ctrl_impl::text_size(double h, double w) { m_text_width = w; m_text_height = h; m_yc2 = m_y2 - m_text_height * 2.0; m_yt1 = m_y2 - m_text_height * 2.0; calc_spline_box(); } //------------------------------------------------------------------------ void gamma_ctrl_impl::border_width(double t, double extra) { m_border_width = t; m_border_extra = extra; calc_spline_box(); } //------------------------------------------------------------------------ void gamma_ctrl_impl::values(double kx1, double ky1, double kx2, double ky2) { m_gamma_spline.values(kx1, ky1, kx2, ky2); } //------------------------------------------------------------------------ void gamma_ctrl_impl::values(double* kx1, double* ky1, double* kx2, double* ky2) const { m_gamma_spline.values(kx1, ky1, kx2, ky2); } //------------------------------------------------------------------------ void gamma_ctrl_impl::rewind(unsigned idx) { double kx1, ky1, kx2, ky2; char tbuf[32]; m_idx = idx; switch(idx) { default: case 0: // Background m_vertex = 0; m_vx[0] = m_x1 - m_border_extra; m_vy[0] = m_y1 - m_border_extra; m_vx[1] = m_x2 + m_border_extra; m_vy[1] = m_y1 - m_border_extra; m_vx[2] = m_x2 + m_border_extra; m_vy[2] = m_y2 + m_border_extra; m_vx[3] = m_x1 - m_border_extra; m_vy[3] = m_y2 + m_border_extra; break; case 1: // Border m_vertex = 0; m_vx[0] = m_x1; m_vy[0] = m_y1; m_vx[1] = m_x2; m_vy[1] = m_y1; m_vx[2] = m_x2; m_vy[2] = m_y2; m_vx[3] = m_x1; m_vy[3] = m_y2; m_vx[4] = m_x1 + m_border_width; m_vy[4] = m_y1 + m_border_width; m_vx[5] = m_x1 + m_border_width; m_vy[5] = m_y2 - m_border_width; m_vx[6] = m_x2 - m_border_width; m_vy[6] = m_y2 - m_border_width; m_vx[7] = m_x2 - m_border_width; m_vy[7] = m_y1 + m_border_width; m_vx[8] = m_xc1 + m_border_width; m_vy[8] = m_yc2 - m_border_width * 0.5; m_vx[9] = m_xc2 - m_border_width; m_vy[9] = m_yc2 - m_border_width * 0.5; m_vx[10] = m_xc2 - m_border_width; m_vy[10] = m_yc2 + m_border_width * 0.5; m_vx[11] = m_xc1 + m_border_width; m_vy[11] = m_yc2 + m_border_width * 0.5; break; case 2: // Curve m_gamma_spline.box(m_xs1, m_ys1, m_xs2, m_ys2); m_curve_poly.width(m_curve_width); m_curve_poly.rewind(0); break; case 3: // Grid m_vertex = 0; m_vx[0] = m_xs1; m_vy[0] = (m_ys1 + m_ys2) * 0.5 - m_grid_width * 0.5; m_vx[1] = m_xs2; m_vy[1] = (m_ys1 + m_ys2) * 0.5 - m_grid_width * 0.5; m_vx[2] = m_xs2; m_vy[2] = (m_ys1 + m_ys2) * 0.5 + m_grid_width * 0.5; m_vx[3] = m_xs1; m_vy[3] = (m_ys1 + m_ys2) * 0.5 + m_grid_width * 0.5; m_vx[4] = (m_xs1 + m_xs2) * 0.5 - m_grid_width * 0.5; m_vy[4] = m_ys1; m_vx[5] = (m_xs1 + m_xs2) * 0.5 - m_grid_width * 0.5; m_vy[5] = m_ys2; m_vx[6] = (m_xs1 + m_xs2) * 0.5 + m_grid_width * 0.5; m_vy[6] = m_ys2; m_vx[7] = (m_xs1 + m_xs2) * 0.5 + m_grid_width * 0.5; m_vy[7] = m_ys1; calc_points(); m_vx[8] = m_xs1; m_vy[8] = m_yp1 - m_grid_width * 0.5; m_vx[9] = m_xp1 - m_grid_width * 0.5; m_vy[9] = m_yp1 - m_grid_width * 0.5; m_vx[10] = m_xp1 - m_grid_width * 0.5; m_vy[10] = m_ys1; m_vx[11] = m_xp1 + m_grid_width * 0.5; m_vy[11] = m_ys1; m_vx[12] = m_xp1 + m_grid_width * 0.5; m_vy[12] = m_yp1 + m_grid_width * 0.5; m_vx[13] = m_xs1; m_vy[13] = m_yp1 + m_grid_width * 0.5; m_vx[14] = m_xs2; m_vy[14] = m_yp2 + m_grid_width * 0.5; m_vx[15] = m_xp2 + m_grid_width * 0.5; m_vy[15] = m_yp2 + m_grid_width * 0.5; m_vx[16] = m_xp2 + m_grid_width * 0.5; m_vy[16] = m_ys2; m_vx[17] = m_xp2 - m_grid_width * 0.5; m_vy[17] = m_ys2; m_vx[18] = m_xp2 - m_grid_width * 0.5; m_vy[18] = m_yp2 - m_grid_width * 0.5; m_vx[19] = m_xs2; m_vy[19] = m_yp2 - m_grid_width * 0.5; break; case 4: // Point1 calc_points(); if(m_p1_active) m_ellipse.init(m_xp2, m_yp2, m_point_size, m_point_size, 32); else m_ellipse.init(m_xp1, m_yp1, m_point_size, m_point_size, 32); break; case 5: // Point2 calc_points(); if(m_p1_active) m_ellipse.init(m_xp1, m_yp1, m_point_size, m_point_size, 32); else m_ellipse.init(m_xp2, m_yp2, m_point_size, m_point_size, 32); break; case 6: // Text m_gamma_spline.values(&kx1, &ky1, &kx2, &ky2); sprintf(tbuf, "%5.3f %5.3f %5.3f %5.3f", kx1, ky1, kx2, ky2); m_text.text(tbuf); m_text.size(m_text_height, m_text_width); m_text.start_point(m_xt1 + m_border_width * 2.0, (m_yt1 + m_yt2) * 0.5 - m_text_height * 0.5); m_text_poly.width(m_text_thickness); m_text_poly.line_join(vcgen_stroke::round_join); m_text_poly.line_cap(vcgen_stroke::round_cap); m_text_poly.rewind(0); break; } } //------------------------------------------------------------------------ unsigned gamma_ctrl_impl::vertex(double* x, double* y) { unsigned cmd = path_cmd_line_to; switch(m_idx) { case 0: if(m_vertex == 0) cmd = path_cmd_move_to; if(m_vertex >= 4) cmd = path_cmd_stop; *x = m_vx[m_vertex]; *y = m_vy[m_vertex]; m_vertex++; break; case 1: if(m_vertex == 0 || m_vertex == 4 || m_vertex == 8) cmd = path_cmd_move_to; if(m_vertex >= 12) cmd = path_cmd_stop; *x = m_vx[m_vertex]; *y = m_vy[m_vertex]; m_vertex++; break; case 2: cmd = m_curve_poly.vertex(x, y); break; case 3: if(m_vertex == 0 || m_vertex == 4 || m_vertex == 8 || m_vertex == 14) cmd = path_cmd_move_to; if(m_vertex >= 20) cmd = path_cmd_stop; *x = m_vx[m_vertex]; *y = m_vy[m_vertex]; m_vertex++; break; case 4: // Point1 case 5: // Point2 cmd = m_ellipse.vertex(x, y); break; case 6: cmd = m_text_poly.vertex(x, y); break; default: cmd = path_cmd_stop; break; } if(!is_stop(cmd)) { transform_xy(x, y); } return cmd; } //------------------------------------------------------------------------ bool gamma_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up) { double kx1, ky1, kx2, ky2; bool ret = false; m_gamma_spline.values(&kx1, &ky1, &kx2, &ky2); if(m_p1_active) { if(left) { kx1 -= 0.005; ret = true; } if(right) { kx1 += 0.005; ret = true; } if(down) { ky1 -= 0.005; ret = true; } if(up) { ky1 += 0.005; ret = true; } } else { if(left) { kx2 += 0.005; ret = true; } if(right) { kx2 -= 0.005; ret = true; } if(down) { ky2 += 0.005; ret = true; } if(up) { ky2 -= 0.005; ret = true; } } if(ret) { m_gamma_spline.values(kx1, ky1, kx2, ky2); } return ret; } //------------------------------------------------------------------------ void gamma_ctrl_impl::change_active_point() { m_p1_active = m_p1_active ? false : true; } //------------------------------------------------------------------------ bool gamma_ctrl_impl::in_rect(double x, double y) const { inverse_transform_xy(&x, &y); return x >= m_x1 && x <= m_x2 && y >= m_y1 && y <= m_y2; } //------------------------------------------------------------------------ bool gamma_ctrl_impl::on_mouse_button_down(double x, double y) { inverse_transform_xy(&x, &y); calc_points(); if(calc_distance(x, y, m_xp1, m_yp1) <= m_point_size + 1) { m_mouse_point = 1; m_pdx = m_xp1 - x; m_pdy = m_yp1 - y; m_p1_active = true; return true; } if(calc_distance(x, y, m_xp2, m_yp2) <= m_point_size + 1) { m_mouse_point = 2; m_pdx = m_xp2 - x; m_pdy = m_yp2 - y; m_p1_active = false; return true; } return false; } //------------------------------------------------------------------------ bool gamma_ctrl_impl::on_mouse_button_up(double, double) { if(m_mouse_point) { m_mouse_point = 0; return true; } return false; } //------------------------------------------------------------------------ bool gamma_ctrl_impl::on_mouse_move(double x, double y, bool button_flag) { inverse_transform_xy(&x, &y); if(!button_flag) { return on_mouse_button_up(x, y); } if(m_mouse_point == 1) { m_xp1 = x + m_pdx; m_yp1 = y + m_pdy; calc_values(); return true; } if(m_mouse_point == 2) { m_xp2 = x + m_pdx; m_yp2 = y + m_pdy; calc_values(); return true; } return false; } } aggdraw-1.3.14/agg2/src/ctrl/agg_gamma_spline.cpp000066400000000000000000000070161417726601400215610ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // class gamma_spline // //---------------------------------------------------------------------------- #include "ctrl/agg_gamma_spline.h" namespace agg { //------------------------------------------------------------------------ gamma_spline::gamma_spline() : m_x1(0), m_y1(0), m_x2(10), m_y2(10), m_cur_x(0.0) { values(1.0, 1.0, 1.0, 1.0); } //------------------------------------------------------------------------ double gamma_spline::y(double x) const { if(x < 0.0) x = 0.0; if(x > 1.0) x = 1.0; double val = m_spline.get(x); if(val < 0.0) val = 0.0; if(val > 1.0) val = 1.0; return val; } //------------------------------------------------------------------------ void gamma_spline::values(double kx1, double ky1, double kx2, double ky2) { if(kx1 < 0.001) kx1 = 0.001; if(kx1 > 1.999) kx1 = 1.999; if(ky1 < 0.001) ky1 = 0.001; if(ky1 > 1.999) ky1 = 1.999; if(kx2 < 0.001) kx2 = 0.001; if(kx2 > 1.999) kx2 = 1.999; if(ky2 < 0.001) ky2 = 0.001; if(ky2 > 1.999) ky2 = 1.999; m_x[0] = 0.0; m_y[0] = 0.0; m_x[1] = kx1 * 0.25; m_y[1] = ky1 * 0.25; m_x[2] = 1.0 - kx2 * 0.25; m_y[2] = 1.0 - ky2 * 0.25; m_x[3] = 1.0; m_y[3] = 1.0; m_spline.init(4, m_x, m_y); int i; for(i = 0; i < 256; i++) { m_gamma[i] = (unsigned char)(y(double(i) / 255.0) * 255.0); } } //------------------------------------------------------------------------ void gamma_spline::values(double* kx1, double* ky1, double* kx2, double* ky2) const { *kx1 = m_x[1] * 4.0; *ky1 = m_y[1] * 4.0; *kx2 = (1.0 - m_x[2]) * 4.0; *ky2 = (1.0 - m_y[2]) * 4.0; } //------------------------------------------------------------------------ void gamma_spline::box(double x1, double y1, double x2, double y2) { m_x1 = x1; m_y1 = y1; m_x2 = x2; m_y2 = y2; } //------------------------------------------------------------------------ void gamma_spline::rewind(unsigned) { m_cur_x = 0.0; } //------------------------------------------------------------------------ unsigned gamma_spline::vertex(double* vx, double* vy) { if(m_cur_x == 0.0) { *vx = m_x1; *vy = m_y1; m_cur_x += 1.0 / (m_x2 - m_x1); return path_cmd_move_to; } if(m_cur_x > 1.0) { return path_cmd_stop; } *vx = m_x1 + m_cur_x * (m_x2 - m_x1); *vy = m_y1 + y(m_cur_x) * (m_y2 - m_y1); m_cur_x += 1.0 / (m_x2 - m_x1); return path_cmd_line_to; } } aggdraw-1.3.14/agg2/src/ctrl/agg_rbox_ctrl.cpp000066400000000000000000000231471417726601400211260ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // classes rbox_ctrl_impl, rbox_ctrl // //---------------------------------------------------------------------------- #include #include "ctrl/agg_rbox_ctrl.h" namespace agg { //------------------------------------------------------------------------ rbox_ctrl_impl::~rbox_ctrl_impl() { if(m_num_items) { char** item = m_items + m_num_items - 1; while(m_num_items--) { delete *item; --item; } } } //------------------------------------------------------------------------ rbox_ctrl_impl::rbox_ctrl_impl(double x1, double y1, double x2, double y2, bool flip_y) : ctrl(x1, y1, x2, y2, flip_y), m_border_width(1.0), m_border_extra(0.0), m_text_thickness(1.5), m_text_height(9.0), m_text_width(0.0), m_num_items(0), m_cur_item(-1), m_ellipse_poly(m_ellipse), m_text_poly(m_text), m_idx(0), m_vertex(0) { calc_rbox(); } //------------------------------------------------------------------------ void rbox_ctrl_impl::calc_rbox() { m_xs1 = m_x1 + m_border_width; m_ys1 = m_y1 + m_border_width; m_xs2 = m_x2 - m_border_width; m_ys2 = m_y2 - m_border_width; } //------------------------------------------------------------------------ void rbox_ctrl_impl::add_item(const char* text) { if(m_num_items < 32) { m_items[m_num_items] = new char[strlen(text) + 1]; strcpy(m_items[m_num_items], text); m_num_items++; } } //------------------------------------------------------------------------ void rbox_ctrl_impl::border_width(double t, double extra) { m_border_width = t; m_border_extra = extra; calc_rbox(); } //------------------------------------------------------------------------ void rbox_ctrl_impl::text_size(double h, double w) { m_text_width = w; m_text_height = h; } //------------------------------------------------------------------------ void rbox_ctrl_impl::rewind(unsigned idx) { m_idx = idx; m_dy = m_text_height * 2.0; m_draw_item = 0; switch(idx) { default: case 0: // Background m_vertex = 0; m_vx[0] = m_x1 - m_border_extra; m_vy[0] = m_y1 - m_border_extra; m_vx[1] = m_x2 + m_border_extra; m_vy[1] = m_y1 - m_border_extra; m_vx[2] = m_x2 + m_border_extra; m_vy[2] = m_y2 + m_border_extra; m_vx[3] = m_x1 - m_border_extra; m_vy[3] = m_y2 + m_border_extra; break; case 1: // Border m_vertex = 0; m_vx[0] = m_x1; m_vy[0] = m_y1; m_vx[1] = m_x2; m_vy[1] = m_y1; m_vx[2] = m_x2; m_vy[2] = m_y2; m_vx[3] = m_x1; m_vy[3] = m_y2; m_vx[4] = m_x1 + m_border_width; m_vy[4] = m_y1 + m_border_width; m_vx[5] = m_x1 + m_border_width; m_vy[5] = m_y2 - m_border_width; m_vx[6] = m_x2 - m_border_width; m_vy[6] = m_y2 - m_border_width; m_vx[7] = m_x2 - m_border_width; m_vy[7] = m_y1 + m_border_width; break; case 2: // Text m_text.text(m_items[0]); m_text.start_point(m_xs1 + m_dy * 1.5, m_ys1 + m_dy / 2.0); m_text.size(m_text_height, m_text_width); m_text_poly.width(m_text_thickness); m_text_poly.line_join(vcgen_stroke::round_join); m_text_poly.line_cap(vcgen_stroke::round_cap); m_text_poly.rewind(0); break; case 3: // Inactive items m_ellipse.init(m_xs1 + m_dy / 1.3, m_ys1 + m_dy / 1.3, m_text_height / 1.5, m_text_height / 1.5, 32); m_ellipse_poly.width(m_text_thickness); m_ellipse_poly.rewind(0); break; case 4: // Active Item if(m_cur_item >= 0) { m_ellipse.init(m_xs1 + m_dy / 1.3, m_ys1 + m_dy * m_cur_item + m_dy / 1.3, m_text_height / 2.0, m_text_height / 2.0, 32); m_ellipse.rewind(0); } break; } } //------------------------------------------------------------------------ unsigned rbox_ctrl_impl::vertex(double* x, double* y) { unsigned cmd = path_cmd_line_to; switch(m_idx) { case 0: if(m_vertex == 0) cmd = path_cmd_move_to; if(m_vertex >= 4) cmd = path_cmd_stop; *x = m_vx[m_vertex]; *y = m_vy[m_vertex]; m_vertex++; break; case 1: if(m_vertex == 0 || m_vertex == 4) cmd = path_cmd_move_to; if(m_vertex >= 8) cmd = path_cmd_stop; *x = m_vx[m_vertex]; *y = m_vy[m_vertex]; m_vertex++; break; case 2: cmd = m_text_poly.vertex(x, y); if(is_stop(cmd)) { m_draw_item++; if(m_draw_item >= m_num_items) { break; } else { m_text.text(m_items[m_draw_item]); m_text.start_point(m_xs1 + m_dy * 1.5, m_ys1 + m_dy * (m_draw_item + 1) - m_dy / 2.0); m_text_poly.rewind(0); cmd = m_text_poly.vertex(x, y); } } break; case 3: cmd = m_ellipse_poly.vertex(x, y); if(is_stop(cmd)) { m_draw_item++; if(m_draw_item >= m_num_items) { break; } else { m_ellipse.init(m_xs1 + m_dy / 1.3, m_ys1 + m_dy * m_draw_item + m_dy / 1.3, m_text_height / 1.5, m_text_height / 1.5, 32); m_ellipse_poly.rewind(0); cmd = m_ellipse_poly.vertex(x, y); } } break; case 4: if(m_cur_item >= 0) { cmd = m_ellipse.vertex(x, y); } else { cmd = path_cmd_stop; } break; default: cmd = path_cmd_stop; break; } if(!is_stop(cmd)) { transform_xy(x, y); } return cmd; } //------------------------------------------------------------------------ bool rbox_ctrl_impl::in_rect(double x, double y) const { inverse_transform_xy(&x, &y); return x >= m_x1 && x <= m_x2 && y >= m_y1 && y <= m_y2; } //------------------------------------------------------------------------ bool rbox_ctrl_impl::on_mouse_button_down(double x, double y) { inverse_transform_xy(&x, &y); unsigned i; for(i = 0; i < m_num_items; i++) { double xp = m_xs1 + m_dy / 1.3; double yp = m_ys1 + m_dy * i + m_dy / 1.3; if(calc_distance(x, y, xp, yp) <= m_text_height / 1.5) { m_cur_item = int(i); return true; } } return false; } //------------------------------------------------------------------------ bool rbox_ctrl_impl::on_mouse_move(double, double, bool) { return false; } //------------------------------------------------------------------------ bool rbox_ctrl_impl::on_mouse_button_up(double, double) { return false; } //------------------------------------------------------------------------ bool rbox_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up) { if(m_cur_item >= 0) { if(up || right) { m_cur_item++; if(m_cur_item >= int(m_num_items)) { m_cur_item = 0; } return true; } if(down || left) { m_cur_item--; if(m_cur_item < 0) { m_cur_item = m_num_items - 1; } return true; } } return false; } } aggdraw-1.3.14/agg2/src/ctrl/agg_scale_ctrl.cpp000066400000000000000000000211361417726601400212370ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // classes scale_ctrl_impl, scale_ctrl // //---------------------------------------------------------------------------- #include "ctrl/agg_scale_ctrl.h" namespace agg { //------------------------------------------------------------------------ scale_ctrl_impl::scale_ctrl_impl(double x1, double y1, double x2, double y2, bool flip_y) : ctrl(x1, y1, x2, y2, flip_y), m_border_thickness(1.0), m_border_extra((y2 - y1) / 2), m_pdx(0.0), m_move_what(move_nothing), m_value1(0.3), m_value2(0.7), m_min_d(0.01) { calc_box(); } //------------------------------------------------------------------------ void scale_ctrl_impl::calc_box() { m_xs1 = m_x1 + m_border_thickness; m_ys1 = m_y1 + m_border_thickness; m_xs2 = m_x2 - m_border_thickness; m_ys2 = m_y2 - m_border_thickness; } //------------------------------------------------------------------------ void scale_ctrl_impl::border_thickness(double t, double extra) { m_border_thickness = t; m_border_extra = extra; calc_box(); } //------------------------------------------------------------------------ void scale_ctrl_impl::rewind(unsigned idx) { m_idx = idx; switch(idx) { default: case 0: // Background m_vertex = 0; m_vx[0] = m_x1 - m_border_extra; m_vy[0] = m_y1 - m_border_extra; m_vx[1] = m_x2 + m_border_extra; m_vy[1] = m_y1 - m_border_extra; m_vx[2] = m_x2 + m_border_extra; m_vy[2] = m_y2 + m_border_extra; m_vx[3] = m_x1 - m_border_extra; m_vy[3] = m_y2 + m_border_extra; break; case 1: // Border m_vertex = 0; m_vx[0] = m_x1; m_vy[0] = m_y1; m_vx[1] = m_x2; m_vy[1] = m_y1; m_vx[2] = m_x2; m_vy[2] = m_y2; m_vx[3] = m_x1; m_vy[3] = m_y2; m_vx[4] = m_x1 + m_border_thickness; m_vy[4] = m_y1 + m_border_thickness; m_vx[5] = m_x1 + m_border_thickness; m_vy[5] = m_y2 - m_border_thickness; m_vx[6] = m_x2 - m_border_thickness; m_vy[6] = m_y2 - m_border_thickness; m_vx[7] = m_x2 - m_border_thickness; m_vy[7] = m_y1 + m_border_thickness; break; case 2: // pointer1 m_ellipse.init(m_xs1 + (m_xs2 - m_xs1) * m_value1, (m_ys1 + m_ys2) / 2.0, m_y2 - m_y1, m_y2 - m_y1, 32); m_ellipse.rewind(0); break; case 3: // pointer2 m_ellipse.init(m_xs1 + (m_xs2 - m_xs1) * m_value2, (m_ys1 + m_ys2) / 2.0, m_y2 - m_y1, m_y2 - m_y1, 32); m_ellipse.rewind(0); break; case 4: // slider m_vertex = 0; m_vx[0] = m_xs1 + (m_xs2 - m_xs1) * m_value1; m_vy[0] = m_y1 - m_border_extra / 2.0; m_vx[1] = m_xs1 + (m_xs2 - m_xs1) * m_value2; m_vy[1] = m_vy[0]; m_vx[2] = m_vx[1]; m_vy[2] = m_y2 + m_border_extra / 2.0; m_vx[3] = m_vx[0]; m_vy[3] = m_vy[2]; break; } } //------------------------------------------------------------------------ unsigned scale_ctrl_impl::vertex(double* x, double* y) { unsigned cmd = path_cmd_line_to; switch(m_idx) { case 0: case 4: if(m_vertex == 0) cmd = path_cmd_move_to; if(m_vertex >= 4) cmd = path_cmd_stop; *x = m_vx[m_vertex]; *y = m_vy[m_vertex]; m_vertex++; break; case 1: if(m_vertex == 0 || m_vertex == 4) cmd = path_cmd_move_to; if(m_vertex >= 8) cmd = path_cmd_stop; *x = m_vx[m_vertex]; *y = m_vy[m_vertex]; m_vertex++; break; case 2: case 3: cmd = m_ellipse.vertex(x, y); break; default: cmd = path_cmd_stop; break; } if(!is_stop(cmd)) { transform_xy(x, y); } return cmd; } //------------------------------------------------------------------------ bool scale_ctrl_impl::in_rect(double x, double y) const { inverse_transform_xy(&x, &y); return x >= m_x1 && x <= m_x2 && y >= m_y1 && y <= m_y2; } //------------------------------------------------------------------------ bool scale_ctrl_impl::on_mouse_button_down(double x, double y) { inverse_transform_xy(&x, &y); double xp1 = m_xs1 + (m_xs2 - m_xs1) * m_value1; double xp2 = m_xs1 + (m_xs2 - m_xs1) * m_value2; double ys1 = m_y1 - m_border_extra / 2.0; double ys2 = m_y2 + m_border_extra / 2.0; double yp = (m_ys1 + m_ys2) / 2.0; if(x > xp1 && y > ys1 && x < xp2 && y < ys2) { m_pdx = xp1 - x; m_move_what = move_slider; return true; } if(x < xp1 && calc_distance(x, y, xp1, yp) <= m_y2 - m_y1) { m_pdx = xp1 - x; m_move_what = move_value1; return true; } if(x > xp2 && calc_distance(x, y, xp2, yp) <= m_y2 - m_y1) { m_pdx = xp2 - x; m_move_what = move_value2; return true; } return false; } //------------------------------------------------------------------------ bool scale_ctrl_impl::on_mouse_move(double x, double y, bool button_flag) { inverse_transform_xy(&x, &y); if(!button_flag) { return on_mouse_button_up(x, y); } double xp = x + m_pdx; double dv; switch(m_move_what) { case move_value1: m_value1 = (xp - m_xs1) / (m_xs2 - m_xs1); if(m_value1 < 0.0) m_value1 = 0.0; if(m_value1 > m_value2 - m_min_d) m_value1 = m_value2 - m_min_d; return true; case move_value2: m_value2 = (xp - m_xs1) / (m_xs2 - m_xs1); if(m_value2 > 1.0) m_value2 = 1.0; if(m_value2 < m_value1 + m_min_d) m_value2 = m_value1 + m_min_d; return true; case move_slider: dv = m_value2 - m_value1; m_value1 = (xp - m_xs1) / (m_xs2 - m_xs1); m_value2 = m_value1 + dv; if(m_value1 < 0.0) { dv = m_value2 - m_value1; m_value1 = 0.0; m_value2 = m_value1 + dv; } if(m_value2 > 1.0) { dv = m_value2 - m_value1; m_value2 = 1.0; m_value1 = m_value2 - dv; } return true; } return false; } //------------------------------------------------------------------------ bool scale_ctrl_impl::on_mouse_button_up(double, double) { m_move_what = move_nothing; return false; } //------------------------------------------------------------------------ bool scale_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up) { /* if(right || up) { m_value += 0.005; if(m_value > 1.0) m_value = 1.0; return true; } if(left || down) { m_value -= 0.005; if(m_value < 0.0) m_value = 0.0; return true; } */ return false; } } aggdraw-1.3.14/agg2/src/ctrl/agg_slider_ctrl.cpp000066400000000000000000000234701417726601400214350ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // classes slider_ctrl_impl, slider_ctrl // //---------------------------------------------------------------------------- #include #include #include "ctrl/agg_slider_ctrl.h" namespace agg { //------------------------------------------------------------------------ slider_ctrl_impl::slider_ctrl_impl(double x1, double y1, double x2, double y2, bool flip_y) : ctrl(x1, y1, x2, y2, flip_y), m_border_width(1.0), m_border_extra((y2 - y1) / 2), m_text_thickness(1.0), m_pdx(0.0), m_mouse_move(false), m_value(0.5), m_preview_value(0.5), m_min(0.0), m_max(1.0), m_num_steps(0), m_descending(false), m_text_poly(m_text) { m_label[0] = 0; calc_box(); } //------------------------------------------------------------------------ void slider_ctrl_impl::calc_box() { m_xs1 = m_x1 + m_border_width; m_ys1 = m_y1 + m_border_width; m_xs2 = m_x2 - m_border_width; m_ys2 = m_y2 - m_border_width; } //------------------------------------------------------------------------ bool slider_ctrl_impl::normalize_value(bool preview_value_flag) { bool ret = true; if(m_num_steps) { int step = int(m_preview_value * m_num_steps + 0.5); ret = m_value != step / double(m_num_steps); m_value = step / double(m_num_steps); } else { m_value = m_preview_value; } if(preview_value_flag) { m_preview_value = m_value; } return ret; } //------------------------------------------------------------------------ void slider_ctrl_impl::border_width(double t, double extra) { m_border_width = t; m_border_extra = extra; calc_box(); } //------------------------------------------------------------------------ void slider_ctrl_impl::value(double value) { m_preview_value = (value - m_min) / (m_max - m_min); if(m_preview_value > 1.0) m_preview_value = 1.0; if(m_preview_value < 0.0) m_preview_value = 0.0; normalize_value(true); } //------------------------------------------------------------------------ void slider_ctrl_impl::label(const char* fmt) { m_label[0] = 0; if(fmt) { unsigned len = strlen(fmt); if(len > 63) len = 63; memcpy(m_label, fmt, len); m_label[len] = 0; } } //------------------------------------------------------------------------ void slider_ctrl_impl::rewind(unsigned idx) { m_idx = idx; switch(idx) { default: case 0: // Background m_vertex = 0; m_vx[0] = m_x1 - m_border_extra; m_vy[0] = m_y1 - m_border_extra; m_vx[1] = m_x2 + m_border_extra; m_vy[1] = m_y1 - m_border_extra; m_vx[2] = m_x2 + m_border_extra; m_vy[2] = m_y2 + m_border_extra; m_vx[3] = m_x1 - m_border_extra; m_vy[3] = m_y2 + m_border_extra; break; case 1: // Triangle m_vertex = 0; if(m_descending) { m_vx[0] = m_x1; m_vy[0] = m_y1; m_vx[1] = m_x2; m_vy[1] = m_y1; m_vx[2] = m_x1; m_vy[2] = m_y2; m_vx[3] = m_x1; m_vy[3] = m_y1; } else { m_vx[0] = m_x1; m_vy[0] = m_y1; m_vx[1] = m_x2; m_vy[1] = m_y1; m_vx[2] = m_x2; m_vy[2] = m_y2; m_vx[3] = m_x1; m_vy[3] = m_y1; } break; case 2: m_text.text(m_label); if(m_label[0]) { char buf[256]; sprintf(buf, m_label, value()); m_text.text(buf); } m_text.start_point(m_x1, m_y1); m_text.size((m_y2 - m_y1) * 1.2, m_y2 - m_y1); m_text_poly.width(m_text_thickness); m_text_poly.line_join(vcgen_stroke::round_join); m_text_poly.line_cap(vcgen_stroke::round_cap); m_text_poly.rewind(0); break; case 3: // pointer preview m_ellipse.init(m_xs1 + (m_xs2 - m_xs1) * m_preview_value, (m_ys1 + m_ys2) / 2.0, m_y2 - m_y1, m_y2 - m_y1, 32); break; case 4: // pointer normalize_value(false); m_ellipse.init(m_xs1 + (m_xs2 - m_xs1) * m_value, (m_ys1 + m_ys2) / 2.0, m_y2 - m_y1, m_y2 - m_y1, 32); m_ellipse.rewind(0); break; case 5: m_storage.remove_all(); if(m_num_steps) { unsigned i; double d = (m_xs2 - m_xs1) / m_num_steps; if(d > 0.004) d = 0.004; for(i = 0; i < m_num_steps + 1; i++) { double x = m_xs1 + (m_xs2 - m_xs1) * i / m_num_steps; m_storage.move_to(x, m_y1); m_storage.line_to(x - d * (m_x2 - m_x1), m_y1 - m_border_extra); m_storage.line_to(x + d * (m_x2 - m_x1), m_y1 - m_border_extra); } } } } //------------------------------------------------------------------------ unsigned slider_ctrl_impl::vertex(double* x, double* y) { unsigned cmd = path_cmd_line_to; switch(m_idx) { case 0: if(m_vertex == 0) cmd = path_cmd_move_to; if(m_vertex >= 4) cmd = path_cmd_stop; *x = m_vx[m_vertex]; *y = m_vy[m_vertex]; m_vertex++; break; case 1: if(m_vertex == 0) cmd = path_cmd_move_to; if(m_vertex >= 4) cmd = path_cmd_stop; *x = m_vx[m_vertex]; *y = m_vy[m_vertex]; m_vertex++; break; case 2: cmd = m_text_poly.vertex(x, y); break; case 3: case 4: cmd = m_ellipse.vertex(x, y); break; case 5: cmd = m_storage.vertex(x, y); break; default: cmd = path_cmd_stop; break; } if(!is_stop(cmd)) { transform_xy(x, y); } return cmd; } //------------------------------------------------------------------------ bool slider_ctrl_impl::in_rect(double x, double y) const { inverse_transform_xy(&x, &y); return x >= m_x1 && x <= m_x2 && y >= m_y1 && y <= m_y2; } //------------------------------------------------------------------------ bool slider_ctrl_impl::on_mouse_button_down(double x, double y) { inverse_transform_xy(&x, &y); double xp = m_xs1 + (m_xs2 - m_xs1) * m_value; double yp = (m_ys1 + m_ys2) / 2.0; if(calc_distance(x, y, xp, yp) <= m_y2 - m_y1) { m_pdx = xp - x; m_mouse_move = true; return true; } return false; } //------------------------------------------------------------------------ bool slider_ctrl_impl::on_mouse_move(double x, double y, bool button_flag) { inverse_transform_xy(&x, &y); if(!button_flag) { on_mouse_button_up(x, y); return false; } if(m_mouse_move) { double xp = x + m_pdx; m_preview_value = (xp - m_xs1) / (m_xs2 - m_xs1); if(m_preview_value < 0.0) m_preview_value = 0.0; if(m_preview_value > 1.0) m_preview_value = 1.0; return true; } return false; } //------------------------------------------------------------------------ bool slider_ctrl_impl::on_mouse_button_up(double, double) { m_mouse_move = false; normalize_value(true); return true; } //------------------------------------------------------------------------ bool slider_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up) { double d = 0.005; if(m_num_steps) { d = 1.0 / m_num_steps; } if(right || up) { m_preview_value += d; if(m_preview_value > 1.0) m_preview_value = 1.0; normalize_value(true); return true; } if(left || down) { m_preview_value -= d; if(m_preview_value < 0.0) m_preview_value = 0.0; normalize_value(true); return true; } return false; } } aggdraw-1.3.14/agg2/src/ctrl/agg_spline_ctrl.cpp000066400000000000000000000263131417726601400214440ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // classes spline_ctrl_impl, spline_ctrl // //---------------------------------------------------------------------------- #include "ctrl/agg_spline_ctrl.h" namespace agg { //------------------------------------------------------------------------ spline_ctrl_impl::spline_ctrl_impl(double x1, double y1, double x2, double y2, unsigned num_pnt, bool flip_y) : ctrl(x1, y1, x2, y2, flip_y), m_num_pnt(num_pnt), m_border_width(1.0), m_border_extra(0.0), m_curve_width(1.0), m_point_size(3.0), m_curve_poly(m_curve_pnt), m_idx(0), m_vertex(0), m_active_pnt(-1), m_move_pnt(-1), m_pdx(0.0), m_pdy(0.0) { if(m_num_pnt < 4) m_num_pnt = 4; if(m_num_pnt > 32) m_num_pnt = 32; unsigned i; for(i = 0; i < m_num_pnt; i++) { m_xp[i] = double(i) / double(m_num_pnt - 1); m_yp[i] = 0.5; } calc_spline_box(); update_spline(); } //------------------------------------------------------------------------ void spline_ctrl_impl::border_width(double t, double extra) { m_border_width = t; m_border_extra = extra; calc_spline_box(); } //------------------------------------------------------------------------ void spline_ctrl_impl::calc_spline_box() { m_xs1 = m_x1 + m_border_width; m_ys1 = m_y1 + m_border_width; m_xs2 = m_x2 - m_border_width; m_ys2 = m_y2 - m_border_width; } //------------------------------------------------------------------------ void spline_ctrl_impl::update_spline() { int i; m_spline.init(m_num_pnt, m_xp, m_yp); for(i = 0; i < 256; i++) { m_spline_values[i] = m_spline.get(double(i) / 255.0); if(m_spline_values[i] < 0.0) m_spline_values[i] = 0.0; if(m_spline_values[i] > 1.0) m_spline_values[i] = 1.0; m_spline_values8[i] = (int8u)(m_spline_values[i] * 255.0); } } //------------------------------------------------------------------------ void spline_ctrl_impl::calc_curve() { int i; m_curve_pnt.remove_all(); m_curve_pnt.move_to(m_xs1, m_ys1 + (m_ys2 - m_ys1) * m_spline_values[0]); for(i = 1; i < 256; i++) { m_curve_pnt.line_to(m_xs1 + (m_xs2 - m_xs1) * double(i) / 255.0, m_ys1 + (m_ys2 - m_ys1) * m_spline_values[i]); } } //------------------------------------------------------------------------ double spline_ctrl_impl::calc_xp(unsigned idx) { return m_xs1 + (m_xs2 - m_xs1) * m_xp[idx]; } //------------------------------------------------------------------------ double spline_ctrl_impl::calc_yp(unsigned idx) { return m_ys1 + (m_ys2 - m_ys1) * m_yp[idx]; } //------------------------------------------------------------------------ void spline_ctrl_impl::set_xp(unsigned idx, double val) { if(val < 0.0) val = 0.0; if(val > 1.0) val = 1.0; if(idx == 0) { val = 0.0; } else if(idx == m_num_pnt - 1) { val = 1.0; } else { if(val < m_xp[idx - 1] + 0.001) val = m_xp[idx - 1] + 0.001; if(val > m_xp[idx + 1] - 0.001) val = m_xp[idx + 1] - 0.001; } m_xp[idx] = val; } //------------------------------------------------------------------------ void spline_ctrl_impl::set_yp(unsigned idx, double val) { if(val < 0.0) val = 0.0; if(val > 1.0) val = 1.0; m_yp[idx] = val; } //------------------------------------------------------------------------ void spline_ctrl_impl::point(unsigned idx, double x, double y) { if(idx < m_num_pnt) { set_xp(idx, x); set_yp(idx, y); } } //------------------------------------------------------------------------ void spline_ctrl_impl::value(unsigned idx, double y) { if(idx < m_num_pnt) { set_yp(idx, y); } } //------------------------------------------------------------------------ double spline_ctrl_impl::value(double x) const { x = m_spline.get(x); if(x < 0.0) x = 0.0; if(x > 1.0) x = 1.0; return x; } //------------------------------------------------------------------------ void spline_ctrl_impl::rewind(unsigned idx) { unsigned i; m_idx = idx; switch(idx) { default: case 0: // Background m_vertex = 0; m_vx[0] = m_x1 - m_border_extra; m_vy[0] = m_y1 - m_border_extra; m_vx[1] = m_x2 + m_border_extra; m_vy[1] = m_y1 - m_border_extra; m_vx[2] = m_x2 + m_border_extra; m_vy[2] = m_y2 + m_border_extra; m_vx[3] = m_x1 - m_border_extra; m_vy[3] = m_y2 + m_border_extra; break; case 1: // Border m_vertex = 0; m_vx[0] = m_x1; m_vy[0] = m_y1; m_vx[1] = m_x2; m_vy[1] = m_y1; m_vx[2] = m_x2; m_vy[2] = m_y2; m_vx[3] = m_x1; m_vy[3] = m_y2; m_vx[4] = m_x1 + m_border_width; m_vy[4] = m_y1 + m_border_width; m_vx[5] = m_x1 + m_border_width; m_vy[5] = m_y2 - m_border_width; m_vx[6] = m_x2 - m_border_width; m_vy[6] = m_y2 - m_border_width; m_vx[7] = m_x2 - m_border_width; m_vy[7] = m_y1 + m_border_width; break; case 2: // Curve calc_curve(); m_curve_poly.width(m_curve_width); m_curve_poly.rewind(0); break; case 3: // Inactive points m_curve_pnt.remove_all(); for(i = 0; i < m_num_pnt; i++) { if(int(i) != m_active_pnt) { m_ellipse.init(calc_xp(i), calc_yp(i), m_point_size, m_point_size, 32); m_curve_pnt.add_path(m_ellipse, 0, false); } } m_curve_poly.rewind(0); break; case 4: // Active point m_curve_pnt.remove_all(); if(m_active_pnt >= 0) { m_ellipse.init(calc_xp(m_active_pnt), calc_yp(m_active_pnt), m_point_size, m_point_size, 32); m_curve_pnt.add_path(m_ellipse); } m_curve_poly.rewind(0); break; } } //------------------------------------------------------------------------ unsigned spline_ctrl_impl::vertex(double* x, double* y) { unsigned cmd = path_cmd_line_to; switch(m_idx) { case 0: if(m_vertex == 0) cmd = path_cmd_move_to; if(m_vertex >= 4) cmd = path_cmd_stop; *x = m_vx[m_vertex]; *y = m_vy[m_vertex]; m_vertex++; break; case 1: if(m_vertex == 0 || m_vertex == 4) cmd = path_cmd_move_to; if(m_vertex >= 8) cmd = path_cmd_stop; *x = m_vx[m_vertex]; *y = m_vy[m_vertex]; m_vertex++; break; case 2: cmd = m_curve_poly.vertex(x, y); break; case 3: case 4: cmd = m_curve_pnt.vertex(x, y); break; default: cmd = path_cmd_stop; break; } if(!is_stop(cmd)) { transform_xy(x, y); } return cmd; } //------------------------------------------------------------------------ void spline_ctrl_impl::active_point(int i) { m_active_pnt = i; } //------------------------------------------------------------------------ bool spline_ctrl_impl::in_rect(double x, double y) const { inverse_transform_xy(&x, &y); return x >= m_x1 && x <= m_x2 && y >= m_y1 && y <= m_y2; } //------------------------------------------------------------------------ bool spline_ctrl_impl::on_mouse_button_down(double x, double y) { inverse_transform_xy(&x, &y); unsigned i; for(i = 0; i < m_num_pnt; i++) { double xp = calc_xp(i); double yp = calc_yp(i); if(calc_distance(x, y, xp, yp) <= m_point_size + 1) { m_pdx = xp - x; m_pdy = yp - y; m_active_pnt = m_move_pnt = int(i); return true; } } return false; } //------------------------------------------------------------------------ bool spline_ctrl_impl::on_mouse_button_up(double, double) { if(m_move_pnt >= 0) { m_move_pnt = -1; return true; } return false; } //------------------------------------------------------------------------ bool spline_ctrl_impl::on_mouse_move(double x, double y, bool button_flag) { inverse_transform_xy(&x, &y); if(!button_flag) { return on_mouse_button_up(x, y); } if(m_move_pnt >= 0) { double xp = x + m_pdx; double yp = y + m_pdy; set_xp(m_move_pnt, (xp - m_xs1) / (m_xs2 - m_xs1)); set_yp(m_move_pnt, (yp - m_ys1) / (m_ys2 - m_ys1)); update_spline(); return true; } return false; } //------------------------------------------------------------------------ bool spline_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up) { double kx = 0.0; double ky = 0.0; bool ret = false; if(m_active_pnt >= 0) { kx = m_xp[m_active_pnt]; ky = m_yp[m_active_pnt]; if(left) { kx -= 0.001; ret = true; } if(right) { kx += 0.001; ret = true; } if(down) { ky -= 0.001; ret = true; } if(up) { ky += 0.001; ret = true; } } if(ret) { set_xp(m_active_pnt, kx); set_yp(m_active_pnt, ky); update_spline(); } return ret; } } aggdraw-1.3.14/agg2/src/dbg_new/000077500000000000000000000000001417726601400162405ustar00rootroot00000000000000aggdraw-1.3.14/agg2/src/dbg_new/agg_dbg_new.cpp000066400000000000000000000414261417726601400211760ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // Debuging stuff for catching memory leaks and corruptions // //---------------------------------------------------------------------------- #include #include #include #include #include "dbg_new/agg_dbg_new.h" namespace agg { int dbg_new_level = -1; struct dbg_new { unsigned new_count; unsigned del_count; unsigned new_bytes; unsigned del_bytes; unsigned max_count; unsigned max_bytes; unsigned corrupted_count; char file_name[512]; int line; bool report_all; }; dbg_new dbg_new_info[max_dbg_new_level] = { { 0, 0, 0, 0, 0, 0, 0, "", 0, false }, }; #ifdef AGG_DBG_NEW_CHECK_ADDR void* dbg_new_allocations[max_allocations] = { 0, }; unsigned dbg_new_prev_word[max_allocations] = { 0, }; unsigned dbg_new_max_count = 0; #endif //------------------------------------------------------------------------ void add_allocated_addr(void* ptr) { #ifdef AGG_DBG_NEW_CHECK_ADDR if(dbg_new_max_count >= max_allocations) { printf("ADDR_CHECK: limit exceeded\n"); } dbg_new_allocations[dbg_new_max_count] = ptr; memcpy(dbg_new_prev_word + dbg_new_max_count, ((char*)ptr) - sizeof(unsigned), sizeof(unsigned)); dbg_new_max_count++; #endif } //------------------------------------------------------------------------ bool check_and_remove_allocated_addr(void* ptr) { #ifdef AGG_DBG_NEW_CHECK_ADDR unsigned i; for(i = 0; i < dbg_new_max_count; i++) { if(dbg_new_allocations[i] == ptr) { unsigned prev; memcpy(&prev, ((char*)ptr) - sizeof(unsigned), sizeof(unsigned)); if(prev != dbg_new_prev_word[i]) { printf("MEMORY CORRUPTION AT %08x prev=%08x cur=%08x\n", ptr, prev, dbg_new_prev_word[i]); //return false; } if(i < dbg_new_max_count - 1) { memmove(dbg_new_allocations + i, dbg_new_allocations + i + 1, sizeof(void*) * dbg_new_max_count - i - 1); } dbg_new_max_count--; //printf("free ok\n"); return true; } } printf("ATTEMPT TO FREE BAD ADDRESS %08x\n", ptr); return false; #else return true; #endif } //------------------------------------------------------------------------ watchdoggy::watchdoggy(const char* file, int line, bool report_all) { #ifdef _WIN32 if(dbg_new_level == -1) { FILE* fd = fopen("stdout.txt", "wt"); fclose(fd); } #endif dbg_new_level++; ::memset(dbg_new_info + dbg_new_level, 0, sizeof(dbg_new)); if(file == 0) file = ""; int len = strlen(file); if(len > 511) len = 511; ::memcpy(dbg_new_info[dbg_new_level].file_name, file, len); dbg_new_info[dbg_new_level].file_name[len] = 0; dbg_new_info[dbg_new_level].line = line; dbg_new_info[dbg_new_level].report_all = report_all; printf("wd%d started. File:%s line:%d\n", dbg_new_level, file, line); } //------------------------------------------------------------------------ watchdoggy::~watchdoggy() { if(dbg_new_level >= 0) { printf("wd%d stopped. File:%s line:%d\n", dbg_new_level, dbg_new_info[dbg_new_level].file_name, dbg_new_info[dbg_new_level].line); printf("new_count=%u del_count=%u max_count=%u balance=%d\n" "new_bytes=%u del_bytes=%u max_bytes=%u balance=%d " "corrupted_count=%u\n", dbg_new_info[dbg_new_level].new_count, dbg_new_info[dbg_new_level].del_count, dbg_new_info[dbg_new_level].max_count, int(dbg_new_info[dbg_new_level].new_count - dbg_new_info[dbg_new_level].del_count), dbg_new_info[dbg_new_level].new_bytes, dbg_new_info[dbg_new_level].del_bytes, dbg_new_info[dbg_new_level].max_bytes, int(dbg_new_info[dbg_new_level].new_bytes - dbg_new_info[dbg_new_level].del_bytes), dbg_new_info[dbg_new_level].corrupted_count ); dbg_new_level--; } } //------------------------------------------------------------------------ // // This code implements the AUTODIN II polynomial // The variable corresponding to the macro argument "crc" should // be an unsigned long. // Oroginal code by Spencer Garrett // // generated using the AUTODIN II polynomial // x^32 + x^26 + x^23 + x^22 + x^16 + // x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1 // //------------------------------------------------------------------------ static const unsigned crc32tab[256] = { 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d }; //------------------------------------------------------------------------ static unsigned long calcCRC32(const char* buf, unsigned size) { unsigned long crc = (unsigned long)~0; const char* p; unsigned len = 0; unsigned nr = size; for (len += nr, p = buf; nr--; ++p) { crc = (crc >> 8) ^ crc32tab[(crc ^ *p) & 0xff]; } return ~crc; } //------------------------------------------------------------------------ void* dbg_malloc(unsigned size, const char* file, int line) { if(dbg_new_level < 0) { void* ptr = ::malloc(size); printf("%u allocated at %08x %s %d\n", size, ptr, file, line); add_allocated_addr(ptr); return ptr; } // The structure of the allocated memory: // // [USER_SIZE:16 bytes] //allows for keeping proper data alignment // [USER_MEM] // [CRC32_sum:long, actual size depends on architecture] // [test_bytes:256 bytes] //should be enough for checking non-fatal // //corruptions with keeping the line number // //and filename correct // [line:unsigned] // [strlen:unsigned] // [file_name:zero_end_string] unsigned fname_len = ::strlen(file) + 1; unsigned total_size = 16 + // size size + // user_mem sizeof(unsigned long) + // crc32 256 + // zero_bytes sizeof(unsigned) + // line sizeof(unsigned) + // strlen fname_len; // .cpp file_name char* inf_ptr = (char*)::malloc(total_size); char* ret_ptr = inf_ptr + 16; int i; for(i = 0; i < 16; i++) { inf_ptr[i] = (char)(15-i); } ::memcpy(inf_ptr, &size, sizeof(unsigned)); unsigned long crc32_before = calcCRC32(inf_ptr, 16); inf_ptr += 16 + size; char* crc32_ptr = inf_ptr; inf_ptr += sizeof(unsigned long); for(i = 0; i < 256; i++) { *inf_ptr++ = (char)(255-i); } ::memcpy(inf_ptr, &line, sizeof(unsigned)); inf_ptr += sizeof(unsigned); ::memcpy(inf_ptr, &fname_len, sizeof(unsigned)); inf_ptr += sizeof(unsigned); ::strcpy(inf_ptr, file); unsigned long // long just in case crc32_sum = calcCRC32(crc32_ptr + sizeof(unsigned long), 256 + sizeof(unsigned) + sizeof(unsigned) + fname_len); crc32_sum ^= crc32_before; ::memcpy(crc32_ptr, &crc32_sum, sizeof(unsigned long)); dbg_new_info[dbg_new_level].new_count++; dbg_new_info[dbg_new_level].new_bytes += size; int balance = int(dbg_new_info[dbg_new_level].new_count - dbg_new_info[dbg_new_level].del_count); if(balance > 0) { if(balance > int(dbg_new_info[dbg_new_level].max_count)) { dbg_new_info[dbg_new_level].max_count = unsigned(balance); } } balance = int(dbg_new_info[dbg_new_level].new_bytes - dbg_new_info[dbg_new_level].del_bytes); if(balance > 0) { if(balance > int(dbg_new_info[dbg_new_level].max_bytes)) { dbg_new_info[dbg_new_level].max_bytes = unsigned(balance); } } if(dbg_new_info[dbg_new_level].report_all) { printf("wdl%d. %u allocated %08x. %s, %d\n", dbg_new_level, size, ret_ptr, file, line ); } add_allocated_addr(ret_ptr); return ret_ptr; } //------------------------------------------------------------------------ void dbg_free(void* ptr) { if(ptr == 0) { //printf("Null pointer free\n"); return; } if(!check_and_remove_allocated_addr(ptr)) return; if(dbg_new_level < 0) { printf("free at %08x\n", ptr); ::free(ptr); return; } char* free_ptr = (char*)ptr; char* inf_ptr = free_ptr; free_ptr -= 16; unsigned size; ::memcpy(&size, free_ptr, sizeof(unsigned)); unsigned long crc32_before = calcCRC32(free_ptr, 16); inf_ptr += size; unsigned long crc32_sum; ::memcpy(&crc32_sum, inf_ptr, sizeof(unsigned long)); inf_ptr += sizeof(unsigned long); char* crc32_ptr = inf_ptr; inf_ptr += 256; unsigned line; ::memcpy(&line, inf_ptr, sizeof(unsigned)); inf_ptr += sizeof(unsigned); unsigned fname_len; ::memcpy(&fname_len, inf_ptr, sizeof(unsigned)); inf_ptr += sizeof(unsigned); char file[512]; if(fname_len > 511) fname_len = 511; ::memcpy(file, inf_ptr, fname_len); file[fname_len] = 0; if(crc32_sum != (calcCRC32(crc32_ptr, 256 + sizeof(unsigned) + sizeof(unsigned) + fname_len) ^ crc32_before)) { printf("WD%d:MEMORY CORRUPTION AT %08x. Allocated %u bytes in %s, line %d\n", dbg_new_level, ptr, size, file, line); dbg_new_info[dbg_new_level].corrupted_count++; } else { ::free(free_ptr); dbg_new_info[dbg_new_level].del_count++; dbg_new_info[dbg_new_level].del_bytes += size; if(dbg_new_info[dbg_new_level].report_all) { printf("wdl%d. %u freed %08x. %s, %d\n", dbg_new_level, size, free_ptr, file, line ); } } } } #ifdef new #undef new #endif //---------------------------------------------------------------------------- void* operator new (unsigned size, const char* file, int line) { return agg::dbg_malloc(size, file, line); } //---------------------------------------------------------------------------- void* operator new [] (unsigned size, const char* file, int line) { return agg::dbg_malloc(size, file, line); } //---------------------------------------------------------------------------- void operator delete(void *ptr) throw() { agg::dbg_free(ptr); } //---------------------------------------------------------------------------- void operator delete [] (void *ptr) throw() { agg::dbg_free(ptr); } /* #include "dbg_new/agg_dbg_new.h" int main() { AGG_WATCHDOGGY(wd1, true); int* a = new int[100]; a[100] = 0; delete [] a; return 0; } */ aggdraw-1.3.14/agg2/src/platform/000077500000000000000000000000001417726601400164575ustar00rootroot00000000000000aggdraw-1.3.14/agg2/src/platform/BeOS/000077500000000000000000000000001417726601400172475ustar00rootroot00000000000000aggdraw-1.3.14/agg2/src/platform/BeOS/agg_platform_support.cpp000066400000000000000000001011311417726601400242060ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: superstippi@gmx.de //---------------------------------------------------------------------------- // // class platform_support // //---------------------------------------------------------------------------- #include #include #include #include #include #include #include #include #include #include #include #include #include #include "platform/agg_platform_support.h" #include "util/agg_color_conv_rgb8.h" class AGGView : public BView { public: AGGView(BRect frame, agg::platform_support* agg, agg::pix_format_e format, bool flipY) : BView(frame, "AGG View", B_FOLLOW_ALL, B_FRAME_EVENTS | B_WILL_DRAW), fAGG(agg), fFormat(format), fFlipY(flipY), fRedraw(true), fPulse(NULL), fLastPulse(0), fEnableTicks(true) { SetViewColor(B_TRANSPARENT_32_BIT); frame.OffsetTo(0.0, 0.0); fBitmap = new BBitmap(frame, 0, B_RGBA32); if (fBitmap->IsValid()) { memset(fBitmap->Bits(), 0, fBitmap->BitsLength()); fAGG->rbuf_window().attach((uint8*)fBitmap->Bits(), fBitmap->Bounds().IntegerWidth() + 1, fBitmap->Bounds().IntegerHeight() + 1, fFlipY ? -fBitmap->BytesPerRow() : fBitmap->BytesPerRow()); } else { delete fBitmap; fBitmap = NULL; } } virtual ~AGGView() { delete fBitmap; delete fPulse; } virtual void AttachedToWindow() { BMessage message('tick'); BMessenger target(this, Looper()); delete fPulse; // BScreen screen; // TODO: calc screen retrace fPulse = new BMessageRunner(target, &message, 40000); // make sure we call this once fAGG->on_resize(Bounds().IntegerWidth() + 1, Bounds().IntegerHeight() + 1); } virtual void DetachedFromWindow() { delete fPulse; fPulse = NULL; } virtual void MessageReceived(BMessage* message) { bigtime_t now = system_time(); switch (message->what) { case 'tick': // drop messages that have piled up if (/*now - fLastPulse > 30000*/fEnableTicks) { fLastPulse = now; if (!fAGG->wait_mode()) fAGG->on_idle(); Window()->PostMessage('entk', this); fEnableTicks = false; } else { // fprintf(stderr, "dropping tick message (%lld)\n", now - fLastPulse); } break; case 'entk': fEnableTicks = true; if (now - fLastPulse > 30000) { fLastPulse = now; if (!fAGG->wait_mode()) fAGG->on_idle(); } break; default: BView::MessageReceived(message); break; } } virtual void Draw(BRect updateRect) { if (fBitmap) { if (fRedraw) { fAGG->on_draw(); fRedraw = false; } if (fFormat == agg::pix_format_bgra32) { DrawBitmap(fBitmap, updateRect, updateRect); } else { BBitmap* bitmap = new BBitmap(fBitmap->Bounds(), 0, B_RGBA32); agg::rendering_buffer rbuf_src; rbuf_src.attach((uint8*)fBitmap->Bits(), fBitmap->Bounds().IntegerWidth() + 1, fBitmap->Bounds().IntegerHeight() + 1, fFlipY ? -fBitmap->BytesPerRow() : fBitmap->BytesPerRow()); agg::rendering_buffer rbuf_dst; rbuf_dst.attach((uint8*)bitmap->Bits(), bitmap->Bounds().IntegerWidth() + 1, bitmap->Bounds().IntegerHeight() + 1, fFlipY ? -bitmap->BytesPerRow() : bitmap->BytesPerRow()); switch(fFormat) { case agg::pix_format_rgb555: agg::color_conv(&rbuf_dst, &rbuf_src, agg::color_conv_rgb555_to_bgra32()); break; case agg::pix_format_rgb565: agg::color_conv(&rbuf_dst, &rbuf_src, agg::color_conv_rgb565_to_bgra32()); break; case agg::pix_format_rgb24: agg::color_conv(&rbuf_dst, &rbuf_src, agg::color_conv_rgb24_to_bgra32()); break; case agg::pix_format_bgr24: agg::color_conv(&rbuf_dst, &rbuf_src, agg::color_conv_bgr24_to_bgra32()); break; case agg::pix_format_rgba32: agg::color_conv(&rbuf_dst, &rbuf_src, agg::color_conv_rgba32_to_bgra32()); break; case agg::pix_format_argb32: agg::color_conv(&rbuf_dst, &rbuf_src, agg::color_conv_argb32_to_bgra32()); break; case agg::pix_format_abgr32: agg::color_conv(&rbuf_dst, &rbuf_src, agg::color_conv_abgr32_to_bgra32()); break; case agg::pix_format_bgra32: agg::color_conv(&rbuf_dst, &rbuf_src, agg::color_conv_bgra32_to_bgra32()); break; } DrawBitmap(bitmap, updateRect, updateRect); delete bitmap; } } else { FillRect(updateRect); } } virtual void FrameResized(float width, float height) { delete fBitmap; BRect r(0.0, 0.0, width, height); fBitmap = new BBitmap(r, 0, B_RGBA32); if (!fBitmap->IsValid()) { delete fBitmap; fBitmap = NULL; } else { fAGG->rbuf_window().attach((uint8*)fBitmap->Bits(), fBitmap->Bounds().IntegerWidth() + 1, fBitmap->Bounds().IntegerHeight() + 1, fFlipY ? -fBitmap->BytesPerRow() : fBitmap->BytesPerRow()); fAGG->trans_affine_resizing((int)width + 1, (int)height + 1); // pass the event on to AGG fAGG->on_resize((int)width + 1, (int)height + 1); fRedraw = true; Invalidate(); } } virtual void KeyDown(const char* bytes, int32 numBytes) { if (bytes && numBytes > 0) { fLastKeyDown = bytes[0]; bool left = false; bool up = false; bool right = false; bool down = false; switch (fLastKeyDown) { case B_LEFT_ARROW: left = true; break; case B_UP_ARROW: up = true; break; case B_RIGHT_ARROW: right = true; break; case B_DOWN_ARROW: down = true; break; } /* case key_f2: fAGG->copy_window_to_img(agg::platform_support::max_images - 1); fAGG->save_img(agg::platform_support::max_images - 1, "screenshot"); break; }*/ if (fAGG->m_ctrls.on_arrow_keys(left, right, down, up)) { fAGG->on_ctrl_change(); fAGG->force_redraw(); } else { fAGG->on_key(fMouseX, fMouseY, fLastKeyDown, GetKeyFlags()); } // fAGG->on_key(fMouseX, fMouseY, fLastKeyDown, GetKeyFlags()); } } virtual void MouseDown(BPoint where) { BMessage* currentMessage = Window()->CurrentMessage(); if (currentMessage) { if (currentMessage->FindInt32("buttons", (int32*)&fMouseButtons) < B_OK) fMouseButtons = B_PRIMARY_MOUSE_BUTTON; } else fMouseButtons = B_PRIMARY_MOUSE_BUTTON; fMouseX = (int)where.x; fMouseY = fFlipY ? (int)(Bounds().Height() - where.y) : (int)where.y; // pass the event on to AGG if (fMouseButtons == B_PRIMARY_MOUSE_BUTTON) { // left mouse button -> see if to handle in controls fAGG->m_ctrls.set_cur(fMouseX, fMouseY); if (fAGG->m_ctrls.on_mouse_button_down(fMouseX, fMouseY)) { fAGG->on_ctrl_change(); fAGG->force_redraw(); } else { if (fAGG->m_ctrls.in_rect(fMouseX, fMouseY)) { if (fAGG->m_ctrls.set_cur(fMouseX, fMouseY)) { fAGG->on_ctrl_change(); fAGG->force_redraw(); } } else { fAGG->on_mouse_button_down(fMouseX, fMouseY, GetKeyFlags()); } } } else if (fMouseButtons & B_SECONDARY_MOUSE_BUTTON) { // right mouse button -> simple fAGG->on_mouse_button_down(fMouseX, fMouseY, GetKeyFlags()); } SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS); } virtual void MouseMoved(BPoint where, uint32 transit, const BMessage* dragMesage) { // workarround missed mouse up events // (if we react too slowly, app_server might have dropped events) BMessage* currentMessage = Window()->CurrentMessage(); int32 buttons = 0; if (currentMessage->FindInt32("buttons", &buttons) < B_OK) { buttons = 0; } if (!buttons) MouseUp(where); fMouseX = (int)where.x; fMouseY = fFlipY ? (int)(Bounds().Height() - where.y) : (int)where.y; // pass the event on to AGG if (fAGG->m_ctrls.on_mouse_move(fMouseX, fMouseY, (GetKeyFlags() & agg::mouse_left) != 0)) { fAGG->on_ctrl_change(); fAGG->force_redraw(); } else { if (!fAGG->m_ctrls.in_rect(fMouseX, fMouseY)) { fAGG->on_mouse_move(fMouseX, fMouseY, GetKeyFlags()); } } } virtual void MouseUp(BPoint where) { fMouseX = (int)where.x; fMouseY = fFlipY ? (int)(Bounds().Height() - where.y) : (int)where.y; // pass the event on to AGG if (fMouseButtons == B_PRIMARY_MOUSE_BUTTON) { fMouseButtons = 0; if (fAGG->m_ctrls.on_mouse_button_up(fMouseX, fMouseY)) { fAGG->on_ctrl_change(); fAGG->force_redraw(); } fAGG->on_mouse_button_up(fMouseX, fMouseY, GetKeyFlags()); } else if (fMouseButtons == B_SECONDARY_MOUSE_BUTTON) { fMouseButtons = 0; fAGG->on_mouse_button_up(fMouseX, fMouseY, GetKeyFlags()); } } BBitmap* Bitmap() const { return fBitmap; } uint8 LastKeyDown() const { return fLastKeyDown; } uint32 MouseButtons() { uint32 buttons = 0; if (LockLooper()) { buttons = fMouseButtons; UnlockLooper(); } return buttons; } void Update() { // trigger display update if (LockLooper()) { Invalidate(); UnlockLooper(); } } void ForceRedraw() { // force a redraw (fRedraw = true;) // and trigger display update if (LockLooper()) { fRedraw = true; Invalidate(); UnlockLooper(); } } unsigned GetKeyFlags() { uint32 buttons = fMouseButtons; uint32 mods = modifiers(); unsigned flags = 0; if (buttons & B_PRIMARY_MOUSE_BUTTON) flags |= agg::mouse_left; if (buttons & B_SECONDARY_MOUSE_BUTTON) flags |= agg::mouse_right; if (mods & B_SHIFT_KEY) flags |= agg::kbd_shift; if (mods & B_COMMAND_KEY) flags |= agg::kbd_ctrl; return flags; } private: BBitmap* fBitmap; uint8 fLastKeyDown; agg::platform_support* fAGG; agg::pix_format_e fFormat; uint32 fMouseButtons; int32 fMouseX; int32 fMouseY; bool fFlipY; bool fRedraw; BMessageRunner* fPulse; bigtime_t fLastPulse; bool fEnableTicks; }; class AGGWindow : public BWindow { public: AGGWindow() : BWindow(BRect(-50.0, -50.0, -10.0, -10.0), "AGG Application", B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS) { } virtual bool QuitRequested() { be_app->PostMessage(B_QUIT_REQUESTED); return true; } bool Init(BRect frame, agg::platform_support* agg, agg::pix_format_e format, bool flipY, uint32 flags) { MoveTo(frame.LeftTop()); ResizeTo(frame.Width(), frame.Height()); SetFlags(flags); frame.OffsetTo(0.0, 0.0); fView = new AGGView(frame, agg, format, flipY); AddChild(fView); return fView->Bitmap() != NULL; } AGGView* View() const { return fView; } private: AGGView* fView; }; class AGGApplication : public BApplication { public: AGGApplication() : BApplication("application/x-vnd.AGG-AGG") { fWindow = new AGGWindow(); } virtual void ReadyToRun() { if (fWindow) { fWindow->Show(); } } virtual bool Init(agg::platform_support* agg, int width, int height, agg::pix_format_e format, bool flipY, uint32 flags) { // ignore flip_y for now BRect r(50.0, 50.0, 50.0 + width - 1.0, 50.0 + height - 1.0); uint32 windowFlags = B_ASYNCHRONOUS_CONTROLS; if (!(flags & agg::window_resize)) windowFlags |= B_NOT_RESIZABLE; return fWindow->Init(r, agg, format, flipY, windowFlags);; } AGGWindow* Window() const { return fWindow; } private: AGGWindow* fWindow; }; namespace agg { class platform_specific { public: platform_specific(agg::platform_support* agg, agg::pix_format_e format, bool flip_y) : fAGG(agg), fApp(NULL), fFormat(format), fFlipY(flip_y), fTimerStart(system_time()) { memset(fImages, 0, sizeof(fImages)); fApp = new AGGApplication(); } ~platform_specific() { for (int32 i = 0; i < agg::platform_support::max_images; i++) delete fImages[i]; delete fApp; } bool Init(int width, int height, unsigned flags) { return fApp->Init(fAGG, width, height, fFormat, fFlipY, flags); } int Run() { status_t ret = B_NO_INIT; if (fApp) { fApp->Run(); ret = B_OK; } return ret; } void SetTitle(const char* title) { if (fApp && fApp->Window() && fApp->Window()->Lock()) { fApp->Window()->SetTitle(title); fApp->Window()->Unlock(); } } void StartTimer() { fTimerStart = system_time(); } double ElapsedTime() const { return (system_time() - fTimerStart) / 1000.0; } void ForceRedraw() { fApp->Window()->View()->ForceRedraw(); } void UpdateWindow() { fApp->Window()->View()->Update(); } agg::platform_support* fAGG; AGGApplication* fApp; agg::pix_format_e fFormat; bool fFlipY; bigtime_t fTimerStart; BBitmap* fImages[agg::platform_support::max_images]; }; //------------------------------------------------------------------------ platform_support::platform_support(pix_format_e format, bool flip_y) : m_specific(new platform_specific(this, format, flip_y)), m_format(format), m_bpp(32/*m_specific->m_bpp*/), m_window_flags(0), m_wait_mode(true), m_flip_y(flip_y), m_initial_width(10), m_initial_height(10) { strcpy(m_caption, "Anti-Grain Geometry Application"); } //------------------------------------------------------------------------ platform_support::~platform_support() { delete m_specific; } //------------------------------------------------------------------------ void platform_support::caption(const char* cap) { strcpy(m_caption, cap); m_specific->SetTitle(cap); } //------------------------------------------------------------------------ void platform_support::start_timer() { m_specific->StartTimer(); } //------------------------------------------------------------------------ double platform_support::elapsed_time() const { return m_specific->ElapsedTime(); } //------------------------------------------------------------------------ void* platform_support::raw_display_handler() { return NULL;//m_specific->m_current_dc; } //------------------------------------------------------------------------ void platform_support::message(const char* msg) { BAlert* alert = new BAlert("AGG Message", msg, "Ok"); alert->Go(/*NULL*/); } //------------------------------------------------------------------------ bool platform_support::init(unsigned width, unsigned height, unsigned flags) { bool success = m_specific->Init(width, height, flags); m_window_flags = flags; // m_specific->create_pmap(width, height, &m_rbuf_window); m_initial_width = width; m_initial_height = height; on_init(); // m_specific->m_redraw_flag = true; return true; } //------------------------------------------------------------------------ int platform_support::run() { return m_specific->Run(); } //------------------------------------------------------------------------ const char* platform_support::img_ext() const { return ""; } //------------------------------------------------------------------------ // TO DO: Stephan, please fix it. Place the buffer in // struct platform_specific. I think it's enough to allocate it // as an array, somewhat like char m_full_path[MAX_PATH]; const char* platform_support::full_file_name(const char* file_name) { return file_name; } //------------------------------------------------------------------------ bool platform_support::load_img(unsigned idx, const char* file) { if (idx < max_images) { // figure out where we're running from app_info info; status_t ret = be_roster->GetRunningAppInfo(be_app->Team(), &info); if (ret < B_OK) { fprintf(stderr, "GetRunningAppInfo() failed: %s\n", strerror(ret)); return false; } BPath path(&info.ref); ret = path.InitCheck(); if (ret < B_OK) { fprintf(stderr, "making path failed: %s\n", strerror(ret)); return false; } ret = path.GetParent(&path); if (ret < B_OK) { fprintf(stderr, "getting parent folder failed: %s\n", strerror(ret)); return false; } ret = path.Append(file); if (ret < B_OK) { fprintf(stderr, "appending image file name failed: %s\n", strerror(ret)); return false; } BBitmap* transBitmap = BTranslationUtils::GetBitmap(path.Path()); if (transBitmap && transBitmap->IsValid()) { if(transBitmap->ColorSpace() != B_RGB32 && transBitmap->ColorSpace() != B_RGBA32) { // ups we got a smart ass Translator making our live harder delete transBitmap; return false; } color_space format = B_RGB24; switch (m_format) { case pix_format_gray8: format = B_GRAY8; break; case pix_format_rgb555: format = B_RGB15; break; case pix_format_rgb565: format = B_RGB16; break; case pix_format_rgb24: format = B_RGB24_BIG; break; case pix_format_bgr24: format = B_RGB24; break; case pix_format_abgr32: case pix_format_argb32: case pix_format_bgra32: format = B_RGB32; break; case pix_format_rgba32: format = B_RGB32_BIG; break; } BBitmap* bitmap = new BBitmap(transBitmap->Bounds(), 0, format); if (!bitmap || !bitmap->IsValid()) { fprintf(stderr, "failed to allocate temporary bitmap!\n"); delete transBitmap; delete bitmap; return false; } delete m_specific->fImages[idx]; rendering_buffer rbuf_tmp; rbuf_tmp.attach((uint8*)transBitmap->Bits(), transBitmap->Bounds().IntegerWidth() + 1, transBitmap->Bounds().IntegerHeight() + 1, m_flip_y ? -transBitmap->BytesPerRow() : transBitmap->BytesPerRow()); m_specific->fImages[idx] = bitmap; m_rbuf_img[idx].attach((uint8*)bitmap->Bits(), bitmap->Bounds().IntegerWidth() + 1, bitmap->Bounds().IntegerHeight() + 1, m_flip_y ? -bitmap->BytesPerRow() : bitmap->BytesPerRow()); rendering_buffer* dst = &m_rbuf_img[idx]; switch(m_format) { case pix_format_gray8: return false; // color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_gray8()); break; break; case pix_format_rgb555: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb555()); break; break; case pix_format_rgb565: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb565()); break; break; case pix_format_rgb24: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb24()); break; break; case pix_format_bgr24: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_bgr24()); break; break; case pix_format_abgr32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_abgr32()); break; break; case pix_format_argb32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_argb32()); break; break; case pix_format_bgra32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_bgra32()); break; break; case pix_format_rgba32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgba32()); break; break; } delete transBitmap; return true; } else { fprintf(stderr, "failed to load bitmap: '%s'\n", path.Path()); } } return false; } //------------------------------------------------------------------------ bool platform_support::save_img(unsigned idx, const char* file) { // TODO: implement using BTranslatorRoster and friends return false; } //------------------------------------------------------------------------ bool platform_support::create_img(unsigned idx, unsigned width, unsigned height) { if(idx < max_images) { if(width == 0) width = m_specific->fApp->Window()->View()->Bitmap()->Bounds().IntegerWidth() + 1; if(height == 0) height = m_specific->fApp->Window()->View()->Bitmap()->Bounds().IntegerHeight() + 1; BBitmap* bitmap = new BBitmap(BRect(0.0, 0.0, width - 1, height - 1), 0, B_RGBA32);; if (bitmap && bitmap->IsValid()) { delete m_specific->fImages[idx]; m_specific->fImages[idx] = bitmap; m_rbuf_img[idx].attach((uint8*)bitmap->Bits(), width, height, m_flip_y ? -bitmap->BytesPerRow() : bitmap->BytesPerRow()); return true; } else { delete bitmap; } } return false; } //------------------------------------------------------------------------ void platform_support::force_redraw() { m_specific->ForceRedraw(); } //------------------------------------------------------------------------ void platform_support::update_window() { m_specific->UpdateWindow(); } //------------------------------------------------------------------------ void platform_support::on_init() {} void platform_support::on_resize(int sx, int sy) {} void platform_support::on_idle() {} void platform_support::on_mouse_move(int x, int y, unsigned flags) {} void platform_support::on_mouse_button_down(int x, int y, unsigned flags) {} void platform_support::on_mouse_button_up(int x, int y, unsigned flags) {} void platform_support::on_key(int x, int y, unsigned key, unsigned flags) {} void platform_support::on_ctrl_change() {} void platform_support::on_draw() {} void platform_support::on_post_draw(void* raw_handler) {} } //---------------------------------------------------------------------------- int agg_main(int argc, char* argv[]); int main(int argc, char* argv[]) { return agg_main(argc, argv); } aggdraw-1.3.14/agg2/src/platform/X11/000077500000000000000000000000001417726601400170305ustar00rootroot00000000000000aggdraw-1.3.14/agg2/src/platform/X11/agg_platform_support.cpp000066400000000000000000001377321417726601400240070ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // class platform_support. X11 version. // //---------------------------------------------------------------------------- #include #include #include #include #include #include #include #include #include #include "agg_basics.h" #include "util/agg_color_conv_rgb8.h" #include "platform/agg_platform_support.h" namespace agg { //------------------------------------------------------------------------ class platform_specific { public: platform_specific(pix_format_e format, bool flip_y); ~platform_specific(); void caption(const char* capt); void put_image(const rendering_buffer* src); pix_format_e m_format; pix_format_e m_sys_format; int m_byte_order; bool m_flip_y; unsigned m_bpp; unsigned m_sys_bpp; Display* m_display; int m_screen; int m_depth; Visual* m_visual; Window m_window; GC m_gc; XImage* m_ximg_window; XSetWindowAttributes m_window_attributes; Atom m_close_atom; unsigned char* m_buf_window; unsigned char* m_buf_img[platform_support::max_images]; unsigned m_keymap[256]; bool m_update_flag; bool m_resize_flag; bool m_initialized; //bool m_wait_mode; clock_t m_sw_start; }; //------------------------------------------------------------------------ platform_specific::platform_specific(pix_format_e format, bool flip_y) : m_format(format), m_sys_format(pix_format_undefined), m_byte_order(LSBFirst), m_flip_y(flip_y), m_bpp(0), m_sys_bpp(0), m_display(0), m_screen(0), m_depth(0), m_visual(0), m_window(0), m_gc(0), m_ximg_window(0), m_close_atom(0), m_buf_window(0), m_update_flag(true), m_resize_flag(true), m_initialized(false) //m_wait_mode(true) { memset(m_buf_img, 0, sizeof(m_buf_img)); unsigned i; for(i = 0; i < 256; i++) { m_keymap[i] = i; } m_keymap[XK_Pause&0xFF] = key_pause; m_keymap[XK_Clear&0xFF] = key_clear; m_keymap[XK_KP_0&0xFF] = key_kp0; m_keymap[XK_KP_1&0xFF] = key_kp1; m_keymap[XK_KP_2&0xFF] = key_kp2; m_keymap[XK_KP_3&0xFF] = key_kp3; m_keymap[XK_KP_4&0xFF] = key_kp4; m_keymap[XK_KP_5&0xFF] = key_kp5; m_keymap[XK_KP_6&0xFF] = key_kp6; m_keymap[XK_KP_7&0xFF] = key_kp7; m_keymap[XK_KP_8&0xFF] = key_kp8; m_keymap[XK_KP_9&0xFF] = key_kp9; m_keymap[XK_KP_Insert&0xFF] = key_kp0; m_keymap[XK_KP_End&0xFF] = key_kp1; m_keymap[XK_KP_Down&0xFF] = key_kp2; m_keymap[XK_KP_Page_Down&0xFF] = key_kp3; m_keymap[XK_KP_Left&0xFF] = key_kp4; m_keymap[XK_KP_Begin&0xFF] = key_kp5; m_keymap[XK_KP_Right&0xFF] = key_kp6; m_keymap[XK_KP_Home&0xFF] = key_kp7; m_keymap[XK_KP_Up&0xFF] = key_kp8; m_keymap[XK_KP_Page_Up&0xFF] = key_kp9; m_keymap[XK_KP_Delete&0xFF] = key_kp_period; m_keymap[XK_KP_Decimal&0xFF] = key_kp_period; m_keymap[XK_KP_Divide&0xFF] = key_kp_divide; m_keymap[XK_KP_Multiply&0xFF] = key_kp_multiply; m_keymap[XK_KP_Subtract&0xFF] = key_kp_minus; m_keymap[XK_KP_Add&0xFF] = key_kp_plus; m_keymap[XK_KP_Enter&0xFF] = key_kp_enter; m_keymap[XK_KP_Equal&0xFF] = key_kp_equals; m_keymap[XK_Up&0xFF] = key_up; m_keymap[XK_Down&0xFF] = key_down; m_keymap[XK_Right&0xFF] = key_right; m_keymap[XK_Left&0xFF] = key_left; m_keymap[XK_Insert&0xFF] = key_insert; m_keymap[XK_Home&0xFF] = key_delete; m_keymap[XK_End&0xFF] = key_end; m_keymap[XK_Page_Up&0xFF] = key_page_up; m_keymap[XK_Page_Down&0xFF] = key_page_down; m_keymap[XK_F1&0xFF] = key_f1; m_keymap[XK_F2&0xFF] = key_f2; m_keymap[XK_F3&0xFF] = key_f3; m_keymap[XK_F4&0xFF] = key_f4; m_keymap[XK_F5&0xFF] = key_f5; m_keymap[XK_F6&0xFF] = key_f6; m_keymap[XK_F7&0xFF] = key_f7; m_keymap[XK_F8&0xFF] = key_f8; m_keymap[XK_F9&0xFF] = key_f9; m_keymap[XK_F10&0xFF] = key_f10; m_keymap[XK_F11&0xFF] = key_f11; m_keymap[XK_F12&0xFF] = key_f12; m_keymap[XK_F13&0xFF] = key_f13; m_keymap[XK_F14&0xFF] = key_f14; m_keymap[XK_F15&0xFF] = key_f15; m_keymap[XK_Num_Lock&0xFF] = key_numlock; m_keymap[XK_Caps_Lock&0xFF] = key_capslock; m_keymap[XK_Scroll_Lock&0xFF] = key_scrollock; switch(m_format) { case pix_format_gray8: m_bpp = 8; break; case pix_format_rgb565: case pix_format_rgb555: m_bpp = 16; break; case pix_format_rgb24: case pix_format_bgr24: m_bpp = 24; break; case pix_format_bgra32: case pix_format_abgr32: case pix_format_argb32: case pix_format_rgba32: m_bpp = 32; break; } m_sw_start = clock(); } //------------------------------------------------------------------------ platform_specific::~platform_specific() { } //------------------------------------------------------------------------ void platform_specific::caption(const char* capt) { XTextProperty tp; tp.value = (unsigned char *)capt; tp.encoding = XA_WM_NAME; tp.format = 8; tp.nitems = strlen(capt); XSetWMName(m_display, m_window, &tp); XStoreName(m_display, m_window, capt); XSetIconName(m_display, m_window, capt); XSetWMIconName(m_display, m_window, &tp); } //------------------------------------------------------------------------ void platform_specific::put_image(const rendering_buffer* src) { if(m_ximg_window == 0) return; m_ximg_window->data = (char*)m_buf_window; if(m_format == m_sys_format) { XPutImage(m_display, m_window, m_gc, m_ximg_window, 0, 0, 0, 0, src->width(), src->height()); } else { int row_len = src->width() * m_sys_bpp / 8; unsigned char* buf_tmp = new unsigned char[row_len * src->height()]; rendering_buffer rbuf_tmp; rbuf_tmp.attach(buf_tmp, src->width(), src->height(), m_flip_y ? -row_len : row_len); switch(m_sys_format) { case pix_format_rgb555: switch(m_format) { case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_rgb555()); break; case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_rgb555()); break; case pix_format_rgb24: color_conv(&rbuf_tmp, src, color_conv_rgb24_to_rgb555()); break; case pix_format_bgr24: color_conv(&rbuf_tmp, src, color_conv_bgr24_to_rgb555()); break; case pix_format_rgba32: color_conv(&rbuf_tmp, src, color_conv_rgba32_to_rgb555()); break; case pix_format_argb32: color_conv(&rbuf_tmp, src, color_conv_argb32_to_rgb555()); break; case pix_format_bgra32: color_conv(&rbuf_tmp, src, color_conv_bgra32_to_rgb555()); break; case pix_format_abgr32: color_conv(&rbuf_tmp, src, color_conv_abgr32_to_rgb555()); break; } break; case pix_format_rgb565: switch(m_format) { case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_rgb565()); break; case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_rgb565()); break; case pix_format_rgb24: color_conv(&rbuf_tmp, src, color_conv_rgb24_to_rgb565()); break; case pix_format_bgr24: color_conv(&rbuf_tmp, src, color_conv_bgr24_to_rgb565()); break; case pix_format_rgba32: color_conv(&rbuf_tmp, src, color_conv_rgba32_to_rgb565()); break; case pix_format_argb32: color_conv(&rbuf_tmp, src, color_conv_argb32_to_rgb565()); break; case pix_format_bgra32: color_conv(&rbuf_tmp, src, color_conv_bgra32_to_rgb565()); break; case pix_format_abgr32: color_conv(&rbuf_tmp, src, color_conv_abgr32_to_rgb565()); break; } break; case pix_format_rgba32: switch(m_format) { case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_rgba32()); break; case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_rgba32()); break; case pix_format_rgb24: color_conv(&rbuf_tmp, src, color_conv_rgb24_to_rgba32()); break; case pix_format_bgr24: color_conv(&rbuf_tmp, src, color_conv_bgr24_to_rgba32()); break; case pix_format_rgba32: color_conv(&rbuf_tmp, src, color_conv_rgba32_to_rgba32()); break; case pix_format_argb32: color_conv(&rbuf_tmp, src, color_conv_argb32_to_rgba32()); break; case pix_format_bgra32: color_conv(&rbuf_tmp, src, color_conv_bgra32_to_rgba32()); break; case pix_format_abgr32: color_conv(&rbuf_tmp, src, color_conv_abgr32_to_rgba32()); break; } break; case pix_format_abgr32: switch(m_format) { case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_abgr32()); break; case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_abgr32()); break; case pix_format_rgb24: color_conv(&rbuf_tmp, src, color_conv_rgb24_to_abgr32()); break; case pix_format_bgr24: color_conv(&rbuf_tmp, src, color_conv_bgr24_to_abgr32()); break; case pix_format_abgr32: color_conv(&rbuf_tmp, src, color_conv_abgr32_to_abgr32()); break; case pix_format_rgba32: color_conv(&rbuf_tmp, src, color_conv_rgba32_to_abgr32()); break; case pix_format_argb32: color_conv(&rbuf_tmp, src, color_conv_argb32_to_abgr32()); break; case pix_format_bgra32: color_conv(&rbuf_tmp, src, color_conv_bgra32_to_abgr32()); break; } break; case pix_format_argb32: switch(m_format) { case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_argb32()); break; case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_argb32()); break; case pix_format_rgb24: color_conv(&rbuf_tmp, src, color_conv_rgb24_to_argb32()); break; case pix_format_bgr24: color_conv(&rbuf_tmp, src, color_conv_bgr24_to_argb32()); break; case pix_format_rgba32: color_conv(&rbuf_tmp, src, color_conv_rgba32_to_argb32()); break; case pix_format_argb32: color_conv(&rbuf_tmp, src, color_conv_argb32_to_argb32()); break; case pix_format_abgr32: color_conv(&rbuf_tmp, src, color_conv_abgr32_to_argb32()); break; case pix_format_bgra32: color_conv(&rbuf_tmp, src, color_conv_bgra32_to_argb32()); break; } break; case pix_format_bgra32: switch(m_format) { case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_bgra32()); break; case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_bgra32()); break; case pix_format_rgb24: color_conv(&rbuf_tmp, src, color_conv_rgb24_to_bgra32()); break; case pix_format_bgr24: color_conv(&rbuf_tmp, src, color_conv_bgr24_to_bgra32()); break; case pix_format_rgba32: color_conv(&rbuf_tmp, src, color_conv_rgba32_to_bgra32()); break; case pix_format_argb32: color_conv(&rbuf_tmp, src, color_conv_argb32_to_bgra32()); break; case pix_format_abgr32: color_conv(&rbuf_tmp, src, color_conv_abgr32_to_bgra32()); break; case pix_format_bgra32: color_conv(&rbuf_tmp, src, color_conv_bgra32_to_bgra32()); break; } break; } m_ximg_window->data = (char*)buf_tmp; XPutImage(m_display, m_window, m_gc, m_ximg_window, 0, 0, 0, 0, src->width(), src->height()); delete [] buf_tmp; } } //------------------------------------------------------------------------ platform_support::platform_support(pix_format_e format, bool flip_y) : m_specific(new platform_specific(format, flip_y)), m_format(format), m_bpp(m_specific->m_bpp), m_window_flags(0), m_wait_mode(true), m_flip_y(flip_y), m_initial_width(10), m_initial_height(10) { strcpy(m_caption, "AGG Application"); } //------------------------------------------------------------------------ platform_support::~platform_support() { delete m_specific; } //------------------------------------------------------------------------ void platform_support::caption(const char* cap) { strcpy(m_caption, cap); if(m_specific->m_initialized) { m_specific->caption(cap); } } //------------------------------------------------------------------------ enum { xevent_mask = PointerMotionMask| ButtonPressMask| ButtonReleaseMask| ExposureMask| KeyPressMask| StructureNotifyMask }; //------------------------------------------------------------------------ bool platform_support::init(unsigned width, unsigned height, unsigned flags) { m_window_flags = flags; m_specific->m_display = XOpenDisplay(NULL); if(m_specific->m_display == 0) { fprintf(stderr, "Unable to open DISPLAY!\n"); return false; } m_specific->m_screen = XDefaultScreen(m_specific->m_display); m_specific->m_depth = XDefaultDepth(m_specific->m_display, m_specific->m_screen); m_specific->m_visual = XDefaultVisual(m_specific->m_display, m_specific->m_screen); unsigned long r_mask = m_specific->m_visual->red_mask; unsigned long g_mask = m_specific->m_visual->green_mask; unsigned long b_mask = m_specific->m_visual->blue_mask; //printf("depth=%d, red=%08x, green=%08x, blue=%08x\n", // m_specific->m_depth, // m_specific->m_visual->red_mask, // m_specific->m_visual->green_mask, // m_specific->m_visual->blue_mask); // // NOT COMPLETED YET! // // Try to find an appropriate Visual if the default doesn't fit. // if(m_specific->m_depth < 15 || // r_mask == 0 || g_mask == 0 || b_mask == 0) // { // // // This is an attempt to find an appropriate Visual if // // the default one doesn't match the minumum requirements // static int depth[] = { 32, 24, 16, 15 }; // int i; // for(int i = 0; i < 4; i++) // { // XVisualInfo vi; // if(XMatchVisualInfo(m_specific->m_display, // m_specific->m_screen, // depth[i], // TrueColor, // &vi)) // { // // printf("TrueColor depth=%d, red=%08x, green=%08x, blue=%08x, bits=%d\n", // // vi.depth, // // vi.visual->red_mask, // // vi.visual->green_mask, // // vi.visual->blue_mask, // // vi.bits_per_rgb); // m_specific->m_depth = vi.depth; // m_specific->m_visual = vi.visual; // r_mask = m_specific->m_visual->red_mask; // g_mask = m_specific->m_visual->green_mask; // b_mask = m_specific->m_visual->blue_mask; // break; // } // if(XMatchVisualInfo(m_specific->m_display, // m_specific->m_screen, // depth[i], // DirectColor, // &vi)) // { // // printf("DirectColor depth=%d, red=%08x, green=%08x, blue=%08x, bits=%d\n", // // vi.depth, // // vi.visual->red_mask, // // vi.visual->green_mask, // // vi.visual->blue_mask, // // vi.bits_per_rgb); // m_specific->m_depth = vi.depth; // m_specific->m_visual = vi.visual; // r_mask = m_specific->m_visual->red_mask; // g_mask = m_specific->m_visual->green_mask; // b_mask = m_specific->m_visual->blue_mask; // break; // } // } // } if(m_specific->m_depth < 15 || r_mask == 0 || g_mask == 0 || b_mask == 0) { fprintf(stderr, "There's no Visual compatible with minimal AGG requirements:\n" "At least 15-bit color depth and True- or DirectColor class.\n\n"); XCloseDisplay(m_specific->m_display); return false; } int t = 1; int hw_byte_order = LSBFirst; if(*(char*)&t == 0) hw_byte_order = MSBFirst; // Perceive SYS-format by mask switch(m_specific->m_depth) { case 15: m_specific->m_sys_bpp = 16; if(r_mask == 0x7C00 && g_mask == 0x3E0 && b_mask == 0x1F) { m_specific->m_sys_format = pix_format_rgb555; m_specific->m_byte_order = hw_byte_order; } break; case 16: m_specific->m_sys_bpp = 16; if(r_mask == 0xF800 && g_mask == 0x7E0 && b_mask == 0x1F) { m_specific->m_sys_format = pix_format_rgb565; m_specific->m_byte_order = hw_byte_order; } break; case 24: case 32: m_specific->m_sys_bpp = 32; if(g_mask == 0xFF00) { if(r_mask == 0xFF && b_mask == 0xFF0000) { switch(m_specific->m_format) { case pix_format_rgba32: m_specific->m_sys_format = pix_format_rgba32; m_specific->m_byte_order = LSBFirst; break; case pix_format_abgr32: m_specific->m_sys_format = pix_format_abgr32; m_specific->m_byte_order = MSBFirst; break; default: m_specific->m_byte_order = hw_byte_order; m_specific->m_sys_format = (hw_byte_order == LSBFirst) ? pix_format_rgba32 : pix_format_abgr32; break; } } if(r_mask == 0xFF0000 && b_mask == 0xFF) { switch(m_specific->m_format) { case pix_format_argb32: m_specific->m_sys_format = pix_format_argb32; m_specific->m_byte_order = MSBFirst; break; case pix_format_bgra32: m_specific->m_sys_format = pix_format_bgra32; m_specific->m_byte_order = LSBFirst; break; default: m_specific->m_byte_order = hw_byte_order; m_specific->m_sys_format = (hw_byte_order == MSBFirst) ? pix_format_argb32 : pix_format_bgra32; break; } } } break; } if(m_specific->m_sys_format == pix_format_undefined) { fprintf(stderr, "RGB masks are not compatible with AGG pixel formats:\n" "R=%08x, R=%08x, B=%08x\n", r_mask, g_mask, b_mask); XCloseDisplay(m_specific->m_display); return false; } memset(&m_specific->m_window_attributes, 0, sizeof(m_specific->m_window_attributes)); m_specific->m_window_attributes.border_pixel = XBlackPixel(m_specific->m_display, m_specific->m_screen); m_specific->m_window_attributes.background_pixel = XWhitePixel(m_specific->m_display, m_specific->m_screen); m_specific->m_window_attributes.override_redirect = 0; unsigned long window_mask = CWBackPixel | CWBorderPixel; m_specific->m_window = XCreateWindow(m_specific->m_display, XDefaultRootWindow(m_specific->m_display), 0, 0, width, height, 0, m_specific->m_depth, InputOutput, CopyFromParent, window_mask, &m_specific->m_window_attributes); m_specific->m_gc = XCreateGC(m_specific->m_display, m_specific->m_window, 0, 0); m_specific->m_buf_window = new unsigned char[width * height * (m_bpp / 8)]; memset(m_specific->m_buf_window, 255, width * height * (m_bpp / 8)); m_rbuf_window.attach(m_specific->m_buf_window, width, height, m_flip_y ? -width * (m_bpp / 8) : width * (m_bpp / 8)); m_specific->m_ximg_window = XCreateImage(m_specific->m_display, m_specific->m_visual, //CopyFromParent, m_specific->m_depth, ZPixmap, 0, (char*)m_specific->m_buf_window, width, height, m_specific->m_sys_bpp, width * (m_specific->m_sys_bpp / 8)); m_specific->m_ximg_window->byte_order = m_specific->m_byte_order; m_specific->caption(m_caption); m_initial_width = width; m_initial_height = height; if(!m_specific->m_initialized) { on_init(); m_specific->m_initialized = true; } trans_affine_resizing(width, height); on_resize(width, height); m_specific->m_update_flag = true; XSizeHints *hints = XAllocSizeHints(); if(hints) { if(flags & window_resize) { hints->min_width = 32; hints->min_height = 32; hints->max_width = 4096; hints->max_height = 4096; } else { hints->min_width = width; hints->min_height = height; hints->max_width = width; hints->max_height = height; } hints->flags = PMaxSize | PMinSize; XSetWMNormalHints(m_specific->m_display, m_specific->m_window, hints); XFree(hints); } XMapWindow(m_specific->m_display, m_specific->m_window); XSelectInput(m_specific->m_display, m_specific->m_window, xevent_mask); m_specific->m_close_atom = XInternAtom(m_specific->m_display, "WM_DELETE_WINDOW", false); XSetWMProtocols(m_specific->m_display, m_specific->m_window, &m_specific->m_close_atom, 1); return true; } //------------------------------------------------------------------------ void platform_support::update_window() { m_specific->put_image(&m_rbuf_window); // When m_wait_mode is true we can discard all the events // came while the image is being drawn. In this case // the X server does not accumulate mouse motion events. // When m_wait_mode is false, i.e. we have some idle drawing // we cannot afford to miss any events XSync(m_specific->m_display, m_wait_mode); } //------------------------------------------------------------------------ int platform_support::run() { XFlush(m_specific->m_display); bool quit = false; unsigned flags; int cur_x; int cur_y; while(!quit) { if(m_specific->m_update_flag) { on_draw(); update_window(); m_specific->m_update_flag = false; } if(!m_wait_mode) { if(XPending(m_specific->m_display) == 0) { on_idle(); continue; } } XEvent x_event; XNextEvent(m_specific->m_display, &x_event); // In the Idle mode discard all intermediate MotionNotify events if(!m_wait_mode && x_event.type == MotionNotify) { XEvent te = x_event; for(;;) { if(XPending(m_specific->m_display) == 0) break; XNextEvent(m_specific->m_display, &te); if(te.type != MotionNotify) break; } x_event = te; } switch(x_event.type) { case ConfigureNotify: { if(x_event.xconfigure.width != m_rbuf_window.width() || x_event.xconfigure.height != m_rbuf_window.height()) { int width = x_event.xconfigure.width; int height = x_event.xconfigure.height; delete [] m_specific->m_buf_window; m_specific->m_ximg_window->data = 0; XDestroyImage(m_specific->m_ximg_window); m_specific->m_buf_window = new unsigned char[width * height * (m_bpp / 8)]; m_rbuf_window.attach(m_specific->m_buf_window, width, height, m_flip_y ? -width * (m_bpp / 8) : width * (m_bpp / 8)); m_specific->m_ximg_window = XCreateImage(m_specific->m_display, m_specific->m_visual, //CopyFromParent, m_specific->m_depth, ZPixmap, 0, (char*)m_specific->m_buf_window, width, height, m_specific->m_sys_bpp, width * (m_specific->m_sys_bpp / 8)); m_specific->m_ximg_window->byte_order = m_specific->m_byte_order; trans_affine_resizing(width, height); on_resize(width, height); on_draw(); update_window(); } } break; case Expose: m_specific->put_image(&m_rbuf_window); XFlush(m_specific->m_display); XSync(m_specific->m_display, false); break; case KeyPress: { KeySym key = XLookupKeysym(&x_event.xkey, 0); flags = 0; if(x_event.xkey.state & Button1Mask) flags |= mouse_left; if(x_event.xkey.state & Button3Mask) flags |= mouse_right; if(x_event.xkey.state & ShiftMask) flags |= kbd_shift; if(x_event.xkey.state & ControlMask) flags |= kbd_ctrl; bool left = false; bool up = false; bool right = false; bool down = false; switch(m_specific->m_keymap[key & 0xFF]) { case key_left: left = true; break; case key_up: up = true; break; case key_right: right = true; break; case key_down: down = true; break; case key_f2: copy_window_to_img(max_images - 1); save_img(max_images - 1, "screenshot"); break; } if(m_ctrls.on_arrow_keys(left, right, down, up)) { on_ctrl_change(); force_redraw(); } else { on_key(x_event.xkey.x, m_flip_y ? m_rbuf_window.height() - x_event.xkey.y : x_event.xkey.y, m_specific->m_keymap[key & 0xFF], flags); } } break; case ButtonPress: { flags = 0; if(x_event.xbutton.state & ShiftMask) flags |= kbd_shift; if(x_event.xbutton.state & ControlMask) flags |= kbd_ctrl; if(x_event.xbutton.button == Button1) flags |= mouse_left; if(x_event.xbutton.button == Button3) flags |= mouse_right; cur_x = x_event.xbutton.x; cur_y = m_flip_y ? m_rbuf_window.height() - x_event.xbutton.y : x_event.xbutton.y; if(flags & mouse_left) { if(m_ctrls.on_mouse_button_down(cur_x, cur_y)) { m_ctrls.set_cur(cur_x, cur_y); on_ctrl_change(); force_redraw(); } else { if(m_ctrls.in_rect(cur_x, cur_y)) { if(m_ctrls.set_cur(cur_x, cur_y)) { on_ctrl_change(); force_redraw(); } } else { on_mouse_button_down(cur_x, cur_y, flags); } } } if(flags & mouse_right) { on_mouse_button_down(cur_x, cur_y, flags); } //m_specific->m_wait_mode = m_wait_mode; //m_wait_mode = true; } break; case MotionNotify: { flags = 0; if(x_event.xmotion.state & Button1Mask) flags |= mouse_left; if(x_event.xmotion.state & Button3Mask) flags |= mouse_right; if(x_event.xmotion.state & ShiftMask) flags |= kbd_shift; if(x_event.xmotion.state & ControlMask) flags |= kbd_ctrl; cur_x = x_event.xbutton.x; cur_y = m_flip_y ? m_rbuf_window.height() - x_event.xbutton.y : x_event.xbutton.y; if(m_ctrls.on_mouse_move(cur_x, cur_y, (flags & mouse_left) != 0)) { on_ctrl_change(); force_redraw(); } else { if(!m_ctrls.in_rect(cur_x, cur_y)) { on_mouse_move(cur_x, cur_y, flags); } } } break; case ButtonRelease: { flags = 0; if(x_event.xbutton.state & ShiftMask) flags |= kbd_shift; if(x_event.xbutton.state & ControlMask) flags |= kbd_ctrl; if(x_event.xbutton.button == Button1) flags |= mouse_left; if(x_event.xbutton.button == Button3) flags |= mouse_right; cur_x = x_event.xbutton.x; cur_y = m_flip_y ? m_rbuf_window.height() - x_event.xbutton.y : x_event.xbutton.y; if(flags & mouse_left) { if(m_ctrls.on_mouse_button_up(cur_x, cur_y)) { on_ctrl_change(); force_redraw(); } } if(flags & (mouse_left | mouse_right)) { on_mouse_button_up(cur_x, cur_y, flags); } } //m_wait_mode = m_specific->m_wait_mode; break; case ClientMessage: if((x_event.xclient.format == 32) && (x_event.xclient.data.l[0] == m_specific->m_close_atom)) { quit = true; } break; } } unsigned i = platform_support::max_images; while(i--) { if(m_specific->m_buf_img[i]) { delete [] m_specific->m_buf_img[i]; } } delete [] m_specific->m_buf_window; m_specific->m_ximg_window->data = 0; XDestroyImage(m_specific->m_ximg_window); XFreeGC(m_specific->m_display, m_specific->m_gc); XDestroyWindow(m_specific->m_display, m_specific->m_window); XCloseDisplay(m_specific->m_display); return 0; } //------------------------------------------------------------------------ const char* platform_support::img_ext() const { return ".ppm"; } //------------------------------------------------------------------------ const char* platform_support::full_file_name(const char* file_name) { return file_name; } //------------------------------------------------------------------------ bool platform_support::load_img(unsigned idx, const char* file) { if(idx < max_images) { char buf[1024]; strcpy(buf, file); int len = strlen(buf); if(len < 4 || strcasecmp(buf + len - 4, ".ppm") != 0) { strcat(buf, ".ppm"); } FILE* fd = fopen(buf, "rb"); if(fd == 0) return false; if((len = fread(buf, 1, 1022, fd)) == 0) { fclose(fd); return false; } buf[len] = 0; if(buf[0] != 'P' && buf[1] != '6') { fclose(fd); return false; } char* ptr = buf + 2; while(*ptr && !isdigit(*ptr)) ptr++; if(*ptr == 0) { fclose(fd); return false; } unsigned width = atoi(ptr); if(width == 0 || width > 4096) { fclose(fd); return false; } while(*ptr && isdigit(*ptr)) ptr++; while(*ptr && !isdigit(*ptr)) ptr++; if(*ptr == 0) { fclose(fd); return false; } unsigned height = atoi(ptr); if(height == 0 || height > 4096) { fclose(fd); return false; } while(*ptr && isdigit(*ptr)) ptr++; while(*ptr && !isdigit(*ptr)) ptr++; if(atoi(ptr) != 255) { fclose(fd); return false; } while(*ptr && isdigit(*ptr)) ptr++; if(*ptr == 0) { fclose(fd); return false; } ptr++; fseek(fd, long(ptr - buf), SEEK_SET); create_img(idx, width, height); bool ret = true; if(m_format == pix_format_rgb24) { fread(m_specific->m_buf_img[idx], 1, width * height * 3, fd); } else { unsigned char* buf_img = new unsigned char [width * height * 3]; rendering_buffer rbuf_img; rbuf_img.attach(buf_img, width, height, m_flip_y ? -width * 3 : width * 3); fread(buf_img, 1, width * height * 3, fd); switch(m_format) { case pix_format_rgb555: color_conv(m_rbuf_img+idx, &rbuf_img, color_conv_rgb24_to_rgb555()); break; case pix_format_rgb565: color_conv(m_rbuf_img+idx, &rbuf_img, color_conv_rgb24_to_rgb565()); break; case pix_format_bgr24: color_conv(m_rbuf_img+idx, &rbuf_img, color_conv_rgb24_to_bgr24()); break; case pix_format_rgba32: color_conv(m_rbuf_img+idx, &rbuf_img, color_conv_rgb24_to_rgba32()); break; case pix_format_argb32: color_conv(m_rbuf_img+idx, &rbuf_img, color_conv_rgb24_to_argb32()); break; case pix_format_bgra32: color_conv(m_rbuf_img+idx, &rbuf_img, color_conv_rgb24_to_bgra32()); break; case pix_format_abgr32: color_conv(m_rbuf_img+idx, &rbuf_img, color_conv_rgb24_to_abgr32()); break; default: ret = false; } delete [] buf_img; } fclose(fd); return ret; } return false; } //------------------------------------------------------------------------ bool platform_support::save_img(unsigned idx, const char* file) { if(idx < max_images && rbuf_img(idx).buf()) { char buf[1024]; strcpy(buf, file); int len = strlen(buf); if(len < 4 || strcasecmp(buf + len - 4, ".ppm") != 0) { strcat(buf, ".ppm"); } FILE* fd = fopen(buf, "wb"); if(fd == 0) return false; unsigned w = rbuf_img(idx).width(); unsigned h = rbuf_img(idx).height(); fprintf(fd, "P6\n%d %d\n255\n", w, h); unsigned y; unsigned char* tmp_buf = new unsigned char [w * 3]; for(y = 0; y < rbuf_img(idx).height(); y++) { const unsigned char* src = rbuf_img(idx).row(m_flip_y ? h - 1 - y : y); switch(m_format) { case pix_format_rgb555: color_conv_row(tmp_buf, src, w, color_conv_rgb555_to_rgb24()); break; case pix_format_rgb565: color_conv_row(tmp_buf, src, w, color_conv_rgb565_to_rgb24()); break; case pix_format_bgr24: color_conv_row(tmp_buf, src, w, color_conv_bgr24_to_rgb24()); break; case pix_format_rgb24: color_conv_row(tmp_buf, src, w, color_conv_rgb24_to_rgb24()); break; case pix_format_rgba32: color_conv_row(tmp_buf, src, w, color_conv_rgba32_to_rgb24()); break; case pix_format_argb32: color_conv_row(tmp_buf, src, w, color_conv_argb32_to_rgb24()); break; case pix_format_bgra32: color_conv_row(tmp_buf, src, w, color_conv_bgra32_to_rgb24()); break; case pix_format_abgr32: color_conv_row(tmp_buf, src, w, color_conv_abgr32_to_rgb24()); break; } fwrite(tmp_buf, 1, w * 3, fd); } delete [] tmp_buf; fclose(fd); return true; } return false; } //------------------------------------------------------------------------ bool platform_support::create_img(unsigned idx, unsigned width, unsigned height) { if(idx < max_images) { delete [] m_specific->m_buf_img[idx]; m_specific->m_buf_img[idx] = new unsigned char[width * height * (m_bpp / 8)]; m_rbuf_img[idx].attach(m_specific->m_buf_img[idx], width, height, m_flip_y ? -width * (m_bpp / 8) : width * (m_bpp / 8)); return true; } return false; } //------------------------------------------------------------------------ void platform_support::force_redraw() { m_specific->m_update_flag = true; } //------------------------------------------------------------------------ void platform_support::message(const char* msg) { fprintf(stderr, "%s\n", msg); } //------------------------------------------------------------------------ void platform_support::start_timer() { m_specific->m_sw_start = clock(); } //------------------------------------------------------------------------ double platform_support::elapsed_time() const { clock_t stop = clock(); return double(stop - m_specific->m_sw_start) * 1000.0 / CLOCKS_PER_SEC; } //------------------------------------------------------------------------ void platform_support::on_init() {} void platform_support::on_resize(int sx, int sy) {} void platform_support::on_idle() {} void platform_support::on_mouse_move(int x, int y, unsigned flags) {} void platform_support::on_mouse_button_down(int x, int y, unsigned flags) {} void platform_support::on_mouse_button_up(int x, int y, unsigned flags) {} void platform_support::on_key(int x, int y, unsigned key, unsigned flags) {} void platform_support::on_ctrl_change() {} void platform_support::on_draw() {} void platform_support::on_post_draw(void* raw_handler) {} } int agg_main(int argc, char* argv[]); int main(int argc, char* argv[]) { return agg_main(argc, argv); } aggdraw-1.3.14/agg2/src/platform/mac/000077500000000000000000000000001417726601400172175ustar00rootroot00000000000000aggdraw-1.3.14/agg2/src/platform/mac/agg_mac_pmap.cpp000066400000000000000000000207031417726601400223200ustar00rootroot00000000000000//---------------------------------------------------------------------------- // //---------------------------------------------------------------------------- // Contact: mcseemagg@yahoo.com // baer@karto.baug.ethz.ch //---------------------------------------------------------------------------- // // class pixel_map // //---------------------------------------------------------------------------- #include #include #include #include #include "platform/mac/agg_mac_pmap.h" #include "agg_basics.h" namespace agg { //------------------------------------------------------------------------ pixel_map::~pixel_map() { destroy(); } //------------------------------------------------------------------------ pixel_map::pixel_map() : m_pmap(0), m_buf(0), m_bpp(0), m_img_size(0) { } //------------------------------------------------------------------------ void pixel_map::destroy() { delete[] m_buf; m_buf = NULL; if (m_pmap != nil) { DisposeGWorld(m_pmap); m_pmap = nil; } } //------------------------------------------------------------------------ void pixel_map::create(unsigned width, unsigned height, org_e org, unsigned clear_val) { destroy(); if(width == 0) width = 1; if(height == 0) height = 1; m_bpp = org; Rect r; int row_bytes = calc_row_len (width, m_bpp); MacSetRect(&r, 0, 0, width, height); m_buf = new unsigned char[m_img_size = row_bytes * height]; // The Quicktime version for creating GWorlds is more flexible than the classical function. QTNewGWorldFromPtr (&m_pmap, m_bpp, &r, nil, nil, 0, m_buf, row_bytes); // create_gray_scale_palette(m_pmap); I didn't care about gray scale palettes so far. if(clear_val <= 255) { memset(m_buf, clear_val, m_img_size); } } //------------------------------------------------------------------------ void pixel_map::clear(unsigned clear_val) { if(m_buf) memset(m_buf, clear_val, m_img_size); } //static //This function is just copied from the Win32 plattform support. //Is also seems to be appropriate for MacOS as well, but it is not //thouroughly tested so far. //------------------------------------------------------------------------ unsigned pixel_map::calc_row_len(unsigned width, unsigned bits_per_pixel) { unsigned n = width; unsigned k; switch(bits_per_pixel) { case 1: k = n; n = n >> 3; if(k & 7) n++; break; case 4: k = n; n = n >> 1; if(k & 3) n++; break; case 8: break; case 16: n = n << 1; break; case 24: n = (n << 1) + n; break; case 32: n = n << 2; break; default: n = 0; break; } return ((n + 3) >> 2) << 2; } //------------------------------------------------------------------------ void pixel_map::draw(WindowRef window, const Rect *device_rect, const Rect *pmap_rect) const { if(m_pmap == nil || m_buf == NULL) return; PixMapHandle pm = GetGWorldPixMap (m_pmap); CGrafPtr port = GetWindowPort (window); Rect dest_rect; // Again, I used the Quicktime version. // Good old 'CopyBits' does better interpolation when scaling // but does not support all pixel depths. MacSetRect (&dest_rect, 0, 0, this->width(), this->height()); ImageDescriptionHandle image_description; MakeImageDescriptionForPixMap (pm, &image_description); if (image_description != nil) { DecompressImage (GetPixBaseAddr (pm), image_description, GetPortPixMap (port), nil, &dest_rect, ditherCopy, nil); DisposeHandle ((Handle) image_description); } } //------------------------------------------------------------------------ void pixel_map::draw(WindowRef window, int x, int y, double scale) const { if(m_pmap == nil || m_buf == NULL) return; unsigned width = this->width() * scale; unsigned height = this->height() * scale; Rect rect; SetRect (&rect, x, y, x + width, y + height); draw(window, &rect); } //------------------------------------------------------------------------ void pixel_map::blend(WindowRef window, const Rect *device_rect, const Rect *bmp_rect) const { draw (window, device_rect, bmp_rect); // currently just mapped to drawing method } //------------------------------------------------------------------------ void pixel_map::blend(WindowRef window, int x, int y, double scale) const { draw(window, x, y, scale); // currently just mapped to drawing method } // I let Quicktime handle image import since it supports most popular // image formats such as: // *.psd, *.bmp, *.tif, *.png, *.jpg, *.gif, *.pct, *.pcx //------------------------------------------------------------------------ bool pixel_map::load_from_qt(const char *filename) { FSSpec fss; OSErr err; // get file specification to application directory err = HGetVol(nil, &fss.vRefNum, &fss.parID); if (err == noErr) { CopyCStringToPascal(filename, fss.name); GraphicsImportComponent gi; err = GetGraphicsImporterForFile (&fss, &gi); if (err == noErr) { ImageDescriptionHandle desc; GraphicsImportGetImageDescription(gi, &desc); // For simplicity, all images are currently converted to 32 bit. // create an empty pixelmap short depth = 32; create ((**desc).width, (**desc).height, (org_e)depth, 0xff); DisposeHandle ((Handle)desc); // let Quicktime draw to pixelmap GraphicsImportSetGWorld(gi, m_pmap, nil); GraphicsImportDraw(gi); // Well, this is a hack. The graphics importer sets the alpha channel of the pixelmap to 0x00 // for imported images without alpha channel but this would cause agg to draw an invisible image. // set alpha channel to 0xff unsigned char * buf = m_buf; for (unsigned int size = 0; size < m_img_size; size += 4) { *buf = 0xff; buf += 4; } } } return err == noErr; } //------------------------------------------------------------------------ bool pixel_map::save_as_qt(const char *filename) const { FSSpec fss; OSErr err; // get file specification to application directory err = HGetVol(nil, &fss.vRefNum, &fss.parID); if (err == noErr) { GraphicsExportComponent ge; CopyCStringToPascal(filename, fss.name); // I decided to use PNG as output image file type. // There are a number of other available formats. // Should I check the file suffix to choose the image file format? err = OpenADefaultComponent(GraphicsExporterComponentType, kQTFileTypePNG, &ge); if (err == noErr) { err = GraphicsExportSetInputGWorld(ge, m_pmap); if (err == noErr) { err = GraphicsExportSetOutputFile (ge, &fss); if (err == noErr) { GraphicsExportDoExport(ge, nil); } } CloseComponent(ge); } } return err == noErr; } //------------------------------------------------------------------------ unsigned char* pixel_map::buf() { return m_buf; } //------------------------------------------------------------------------ unsigned pixel_map::width() const { if(m_pmap == nil) return 0; PixMapHandle pm = GetGWorldPixMap (m_pmap); Rect bounds; GetPixBounds (pm, &bounds); return bounds.right - bounds.left; } //------------------------------------------------------------------------ unsigned pixel_map::height() const { if(m_pmap == nil) return 0; PixMapHandle pm = GetGWorldPixMap (m_pmap); Rect bounds; GetPixBounds (pm, &bounds); return bounds.bottom - bounds.top; } //------------------------------------------------------------------------ int pixel_map::row_bytes() const { if(m_pmap == nil) return 0; PixMapHandle pm = GetGWorldPixMap (m_pmap); return calc_row_len(width(), GetPixDepth(pm)); } } aggdraw-1.3.14/agg2/src/platform/mac/agg_platform_support.cpp000066400000000000000000001030761417726601400241700ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.0 // Copyright (C) 2002 Maxim Shemanarev (McSeem) // Copyright (C) 2003 Hansruedi Baer (MacOS support) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com // baer@karto.baug.eth.ch //---------------------------------------------------------------------------- // // class platform_support // //---------------------------------------------------------------------------- // // Note: // I tried to retain the original structure for the Win32 platform as far // as possible. Currently, not all features are implemented but the examples // should work properly. // HB //---------------------------------------------------------------------------- #include #if defined(__MWERKS__) #include "console.h" #endif #include #include "platform/agg_platform_support.h" #include "platform/mac/agg_mac_pmap.h" #include "util/agg_color_conv_rgb8.h" namespace agg { pascal OSStatus DoWindowClose (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData); pascal OSStatus DoWindowDrawContent (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData); pascal OSStatus DoAppQuit (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData); pascal OSStatus DoMouseDown (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData); pascal OSStatus DoMouseUp (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData); pascal OSStatus DoMouseDragged (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData); pascal OSStatus DoKeyDown (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData); pascal OSStatus DoKeyUp (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData); pascal void DoPeriodicTask (EventLoopTimerRef theTimer, void* userData); //------------------------------------------------------------------------ class platform_specific { public: platform_specific(pix_format_e format, bool flip_y); void create_pmap(unsigned width, unsigned height, rendering_buffer* wnd); void display_pmap(WindowRef window, const rendering_buffer* src); bool load_pmap(const char* fn, unsigned idx, rendering_buffer* dst); bool save_pmap(const char* fn, unsigned idx, const rendering_buffer* src); unsigned translate(unsigned keycode); pix_format_e m_format; pix_format_e m_sys_format; bool m_flip_y; unsigned m_bpp; unsigned m_sys_bpp; WindowRef m_window; pixel_map m_pmap_window; pixel_map m_pmap_img[platform_support::max_images]; unsigned m_keymap[256]; unsigned m_last_translated_key; int m_cur_x; int m_cur_y; unsigned m_input_flags; bool m_redraw_flag; UnsignedWide m_sw_freq; UnsignedWide m_sw_start; }; //------------------------------------------------------------------------ platform_specific::platform_specific(pix_format_e format, bool flip_y) : m_format(format), m_sys_format(pix_format_undefined), m_flip_y(flip_y), m_bpp(0), m_sys_bpp(0), m_window(nil), m_last_translated_key(0), m_cur_x(0), m_cur_y(0), m_input_flags(0), m_redraw_flag(true) { memset(m_keymap, 0, sizeof(m_keymap)); //Keyboard input is not yet fully supported nor tested //m_keymap[VK_PAUSE] = key_pause; m_keymap[kClearCharCode] = key_clear; //m_keymap[VK_NUMPAD0] = key_kp0; //m_keymap[VK_NUMPAD1] = key_kp1; //m_keymap[VK_NUMPAD2] = key_kp2; //m_keymap[VK_NUMPAD3] = key_kp3; //m_keymap[VK_NUMPAD4] = key_kp4; //m_keymap[VK_NUMPAD5] = key_kp5; //m_keymap[VK_NUMPAD6] = key_kp6; //m_keymap[VK_NUMPAD7] = key_kp7; //m_keymap[VK_NUMPAD8] = key_kp8; //m_keymap[VK_NUMPAD9] = key_kp9; //m_keymap[VK_DECIMAL] = key_kp_period; //m_keymap[VK_DIVIDE] = key_kp_divide; //m_keymap[VK_MULTIPLY] = key_kp_multiply; //m_keymap[VK_SUBTRACT] = key_kp_minus; //m_keymap[VK_ADD] = key_kp_plus; m_keymap[kUpArrowCharCode] = key_up; m_keymap[kDownArrowCharCode] = key_down; m_keymap[kRightArrowCharCode] = key_right; m_keymap[kLeftArrowCharCode] = key_left; //m_keymap[VK_INSERT] = key_insert; m_keymap[kDeleteCharCode] = key_delete; m_keymap[kHomeCharCode] = key_home; m_keymap[kEndCharCode] = key_end; m_keymap[kPageUpCharCode] = key_page_up; m_keymap[kPageDownCharCode] = key_page_down; //m_keymap[VK_F1] = key_f1; //m_keymap[VK_F2] = key_f2; //m_keymap[VK_F3] = key_f3; //m_keymap[VK_F4] = key_f4; //m_keymap[VK_F5] = key_f5; //m_keymap[VK_F6] = key_f6; //m_keymap[VK_F7] = key_f7; //m_keymap[VK_F8] = key_f8; //m_keymap[VK_F9] = key_f9; //m_keymap[VK_F10] = key_f10; //m_keymap[VK_F11] = key_f11; //m_keymap[VK_F12] = key_f12; //m_keymap[VK_F13] = key_f13; //m_keymap[VK_F14] = key_f14; //m_keymap[VK_F15] = key_f15; //m_keymap[VK_NUMLOCK] = key_numlock; //m_keymap[VK_CAPITAL] = key_capslock; //m_keymap[VK_SCROLL] = key_scrollock; switch(m_format) { case pix_format_gray8: m_sys_format = pix_format_gray8; m_bpp = 8; m_sys_bpp = 8; break; case pix_format_rgb565: case pix_format_rgb555: m_sys_format = pix_format_rgb555; m_bpp = 16; m_sys_bpp = 16; break; case pix_format_rgb24: case pix_format_bgr24: m_sys_format = pix_format_rgb24; m_bpp = 24; m_sys_bpp = 24; break; case pix_format_bgra32: case pix_format_abgr32: case pix_format_argb32: case pix_format_rgba32: m_sys_format = pix_format_argb32; m_bpp = 32; m_sys_bpp = 32; break; } ::Microseconds(&m_sw_freq); ::Microseconds(&m_sw_start); } //------------------------------------------------------------------------ void platform_specific::create_pmap(unsigned width, unsigned height, rendering_buffer* wnd) { m_pmap_window.create(width, height, org_e(m_bpp)); wnd->attach(m_pmap_window.buf(), m_pmap_window.width(), m_pmap_window.height(), m_flip_y ? -m_pmap_window.row_bytes() : m_pmap_window.row_bytes()); } //------------------------------------------------------------------------ void platform_specific::display_pmap(WindowRef window, const rendering_buffer* src) { if(m_sys_format == m_format) { m_pmap_window.draw(window); } else { pixel_map pmap_tmp; pmap_tmp.create(m_pmap_window.width(), m_pmap_window.height(), org_e(m_sys_bpp)); rendering_buffer rbuf_tmp; rbuf_tmp.attach(pmap_tmp.buf(), pmap_tmp.width(), pmap_tmp.height(), m_flip_y ? -pmap_tmp.row_bytes() : pmap_tmp.row_bytes()); switch(m_format) { case pix_format_gray8: return; case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_rgb555()); break; case pix_format_bgr24: color_conv(&rbuf_tmp, src, color_conv_bgr24_to_rgb24()); break; case pix_format_abgr32: color_conv(&rbuf_tmp, src, color_conv_abgr32_to_argb32()); break; case pix_format_bgra32: color_conv(&rbuf_tmp, src, color_conv_bgra32_to_argb32()); break; case pix_format_rgba32: color_conv(&rbuf_tmp, src, color_conv_rgba32_to_argb32()); break; } pmap_tmp.draw(window); } } //------------------------------------------------------------------------ bool platform_specific::save_pmap(const char* fn, unsigned idx, const rendering_buffer* src) { if(m_sys_format == m_format) { return m_pmap_img[idx].save_as_qt(fn); } else { pixel_map pmap_tmp; pmap_tmp.create(m_pmap_img[idx].width(), m_pmap_img[idx].height(), org_e(m_sys_bpp)); rendering_buffer rbuf_tmp; rbuf_tmp.attach(pmap_tmp.buf(), pmap_tmp.width(), pmap_tmp.height(), m_flip_y ? -pmap_tmp.row_bytes() : pmap_tmp.row_bytes()); switch(m_format) { case pix_format_gray8: return false; case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_rgb555()); break; case pix_format_rgb24: color_conv(&rbuf_tmp, src, color_conv_rgb24_to_bgr24()); break; case pix_format_abgr32: color_conv(&rbuf_tmp, src, color_conv_abgr32_to_bgra32()); break; case pix_format_argb32: color_conv(&rbuf_tmp, src, color_conv_argb32_to_bgra32()); break; case pix_format_rgba32: color_conv(&rbuf_tmp, src, color_conv_rgba32_to_bgra32()); break; } return pmap_tmp.save_as_qt(fn); } return true; } //------------------------------------------------------------------------ bool platform_specific::load_pmap(const char* fn, unsigned idx, rendering_buffer* dst) { pixel_map pmap_tmp; if(!pmap_tmp.load_from_qt(fn)) return false; rendering_buffer rbuf_tmp; rbuf_tmp.attach(pmap_tmp.buf(), pmap_tmp.width(), pmap_tmp.height(), m_flip_y ? -pmap_tmp.row_bytes() : pmap_tmp.row_bytes()); m_pmap_img[idx].create(pmap_tmp.width(), pmap_tmp.height(), org_e(m_bpp), 0); dst->attach(m_pmap_img[idx].buf(), m_pmap_img[idx].width(), m_pmap_img[idx].height(), m_flip_y ? -m_pmap_img[idx].row_bytes() : m_pmap_img[idx].row_bytes()); switch(m_format) { case pix_format_gray8: return false; break; case pix_format_rgb555: switch(pmap_tmp.bpp()) { case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb555()); break; case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_rgb555()); break; case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_rgb555()); break; } break; case pix_format_rgb565: switch(pmap_tmp.bpp()) { case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb565()); break; case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_rgb565()); break; case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_rgb565()); break; } break; case pix_format_rgb24: switch(pmap_tmp.bpp()) { case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb24()); break; case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_rgb24()); break; case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_rgb24()); break; } break; case pix_format_bgr24: switch(pmap_tmp.bpp()) { case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_bgr24()); break; case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_bgr24()); break; case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_bgr24()); break; } break; case pix_format_abgr32: switch(pmap_tmp.bpp()) { case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_abgr32()); break; case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_abgr32()); break; case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_abgr32()); break; } break; case pix_format_argb32: switch(pmap_tmp.bpp()) { case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_argb32()); break; case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_argb32()); break; case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_argb32()); break; } break; case pix_format_bgra32: switch(pmap_tmp.bpp()) { case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_bgra32()); break; case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_bgra32()); break; case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_bgra32()); break; } break; case pix_format_rgba32: switch(pmap_tmp.bpp()) { case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgba32()); break; case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_rgba32()); break; case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_rgba32()); break; } break; } return true; } //------------------------------------------------------------------------ unsigned platform_specific::translate(unsigned keycode) { return m_last_translated_key = (keycode > 255) ? 0 : m_keymap[keycode]; } //------------------------------------------------------------------------ platform_support::platform_support(pix_format_e format, bool flip_y) : m_specific(new platform_specific(format, flip_y)), m_format(format), m_bpp(m_specific->m_bpp), m_window_flags(0), m_wait_mode(true), m_flip_y(flip_y), m_initial_width(10), m_initial_height(10) { strcpy(m_caption, "Anti-Grain Geometry Application"); } //------------------------------------------------------------------------ platform_support::~platform_support() { delete m_specific; } //------------------------------------------------------------------------ void platform_support::caption(const char* cap) { strcpy(m_caption, cap); if(m_specific->m_window) { SetWindowTitleWithCFString (m_specific->m_window, CFStringCreateWithCStringNoCopy (nil, cap, kCFStringEncodingASCII, nil)); } } //------------------------------------------------------------------------ static unsigned get_key_flags(UInt32 wflags) { unsigned flags = 0; if(wflags & shiftKey) flags |= kbd_shift; if(wflags & controlKey) flags |= kbd_ctrl; return flags; } //------------------------------------------------------------------------ void platform_support::message(const char* msg) { SInt16 item; Str255 p_msg; ::CopyCStringToPascal (msg, p_msg); ::StandardAlert (kAlertPlainAlert, "\pAGG Message", p_msg, NULL, &item); } //------------------------------------------------------------------------ void platform_support::start_timer() { ::Microseconds (&(m_specific->m_sw_start)); } //------------------------------------------------------------------------ double platform_support::elapsed_time() const { UnsignedWide stop; ::Microseconds(&stop); return double(stop.lo - m_specific->m_sw_start.lo) * 1e6 / double(m_specific->m_sw_freq.lo); } //------------------------------------------------------------------------ bool platform_support::init(unsigned width, unsigned height, unsigned flags) { if(m_specific->m_sys_format == pix_format_undefined) { return false; } m_window_flags = flags; // application EventTypeSpec eventType; EventHandlerUPP handlerUPP; eventType.eventClass = kEventClassApplication; eventType.eventKind = kEventAppQuit; handlerUPP = NewEventHandlerUPP(DoAppQuit); InstallApplicationEventHandler (handlerUPP, 1, &eventType, nil, nil); eventType.eventClass = kEventClassMouse; eventType.eventKind = kEventMouseDown; handlerUPP = NewEventHandlerUPP(DoMouseDown); InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil); eventType.eventKind = kEventMouseUp; handlerUPP = NewEventHandlerUPP(DoMouseUp); InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil); eventType.eventKind = kEventMouseDragged; handlerUPP = NewEventHandlerUPP(DoMouseDragged); InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil); eventType.eventClass = kEventClassKeyboard; eventType.eventKind = kEventRawKeyDown; handlerUPP = NewEventHandlerUPP(DoKeyDown); InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil); eventType.eventKind = kEventRawKeyUp; handlerUPP = NewEventHandlerUPP(DoKeyUp); InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil); eventType.eventKind = kEventRawKeyRepeat; handlerUPP = NewEventHandlerUPP(DoKeyDown); // 'key repeat' is translated to 'key down' InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil); WindowAttributes windowAttrs; Rect bounds; // window windowAttrs = kWindowCloseBoxAttribute | kWindowCollapseBoxAttribute | kWindowStandardHandlerAttribute; SetRect (&bounds, 0, 0, width, height); OffsetRect (&bounds, 100, 100); CreateNewWindow (kDocumentWindowClass, windowAttrs, &bounds, &m_specific->m_window); if(m_specific->m_window == nil) { return false; } // I assume the text is ASCII. // Change to kCFStringEncodingMacRoman, kCFStringEncodingISOLatin1, kCFStringEncodingUTF8 or what else you need. SetWindowTitleWithCFString (m_specific->m_window, CFStringCreateWithCStringNoCopy (nil, m_caption, kCFStringEncodingASCII, nil)); eventType.eventClass = kEventClassWindow; eventType.eventKind = kEventWindowClose; handlerUPP = NewEventHandlerUPP(DoWindowClose); InstallWindowEventHandler (m_specific->m_window, handlerUPP, 1, &eventType, this, NULL); eventType.eventKind = kEventWindowDrawContent; handlerUPP = NewEventHandlerUPP(DoWindowDrawContent); InstallWindowEventHandler (m_specific->m_window, handlerUPP, 1, &eventType, this, NULL); // Periodic task // Instead of an idle function I use the Carbon event timer. // You may decide to change the wait value which is currently 50 milliseconds. EventLoopRef mainLoop; EventLoopTimerUPP timerUPP; EventLoopTimerRef theTimer; mainLoop = GetMainEventLoop(); timerUPP = NewEventLoopTimerUPP (DoPeriodicTask); InstallEventLoopTimer (mainLoop, 0, 50 * kEventDurationMillisecond, timerUPP, this, &theTimer); m_specific->create_pmap(width, height, &m_rbuf_window); m_initial_width = width; m_initial_height = height; on_init(); on_resize(width, height); m_specific->m_redraw_flag = true; ShowWindow (m_specific->m_window); SetPortWindowPort (m_specific->m_window); return true; } //------------------------------------------------------------------------ int platform_support::run() { RunApplicationEventLoop (); return true; } //------------------------------------------------------------------------ const char* platform_support::img_ext() const { return ".bmp"; } //------------------------------------------------------------------------ const char* platform_support::full_file_name(const char* file_name) { return file_name; } //------------------------------------------------------------------------ bool platform_support::load_img(unsigned idx, const char* file) { if(idx < max_images) { char fn[1024]; strcpy(fn, file); int len = strlen(fn); if(len < 4 || stricmp(fn + len - 4, ".BMP") != 0) { strcat(fn, ".bmp"); } return m_specific->load_pmap(fn, idx, &m_rbuf_img[idx]); } return true; } //------------------------------------------------------------------------ bool platform_support::save_img(unsigned idx, const char* file) { if(idx < max_images) { char fn[1024]; strcpy(fn, file); int len = strlen(fn); if(len < 4 || stricmp(fn + len - 4, ".BMP") != 0) { strcat(fn, ".bmp"); } return m_specific->save_pmap(fn, idx, &m_rbuf_img[idx]); } return true; } //------------------------------------------------------------------------ bool platform_support::create_img(unsigned idx, unsigned width, unsigned height) { if(idx < max_images) { if(width == 0) width = m_specific->m_pmap_window.width(); if(height == 0) height = m_specific->m_pmap_window.height(); m_specific->m_pmap_img[idx].create(width, height, org_e(m_specific->m_bpp)); m_rbuf_img[idx].attach(m_specific->m_pmap_img[idx].buf(), m_specific->m_pmap_img[idx].width(), m_specific->m_pmap_img[idx].height(), m_flip_y ? -m_specific->m_pmap_img[idx].row_bytes() : m_specific->m_pmap_img[idx].row_bytes()); return true; } return false; } //------------------------------------------------------------------------ void platform_support::force_redraw() { Rect bounds; m_specific->m_redraw_flag = true; // on_ctrl_change (); on_draw(); SetRect(&bounds, 0, 0, m_rbuf_window.width(), m_rbuf_window.height()); InvalWindowRect(m_specific->m_window, &bounds); } //------------------------------------------------------------------------ void platform_support::update_window() { m_specific->display_pmap(m_specific->m_window, &m_rbuf_window); } //------------------------------------------------------------------------ void platform_support::on_init() {} void platform_support::on_resize(int sx, int sy) {} void platform_support::on_idle() {} void platform_support::on_mouse_move(int x, int y, unsigned flags) {} void platform_support::on_mouse_button_down(int x, int y, unsigned flags) {} void platform_support::on_mouse_button_up(int x, int y, unsigned flags) {} void platform_support::on_key(int x, int y, unsigned key, unsigned flags) {} void platform_support::on_ctrl_change() {} void platform_support::on_draw() {} void platform_support::on_post_draw(void* raw_handler) {} //------------------------------------------------------------------------ pascal OSStatus DoWindowClose (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData) { userData; QuitApplicationEventLoop (); return CallNextEventHandler (nextHandler, theEvent); } //------------------------------------------------------------------------ pascal OSStatus DoAppQuit (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData) { userData; return CallNextEventHandler (nextHandler, theEvent); } //------------------------------------------------------------------------ pascal OSStatus DoMouseDown (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData) { Point wheresMyMouse; UInt32 modifier; GetEventParameter (theEvent, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &wheresMyMouse); GlobalToLocal (&wheresMyMouse); GetEventParameter (theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifier); platform_support * app = reinterpret_cast(userData); app->m_specific->m_cur_x = wheresMyMouse.h; if(app->flip_y()) { app->m_specific->m_cur_y = app->rbuf_window().height() - wheresMyMouse.v; } else { app->m_specific->m_cur_y = wheresMyMouse.v; } app->m_specific->m_input_flags = mouse_left | get_key_flags(modifier); app->m_ctrls.set_cur(app->m_specific->m_cur_x, app->m_specific->m_cur_y); if(app->m_ctrls.on_mouse_button_down(app->m_specific->m_cur_x, app->m_specific->m_cur_y)) { app->on_ctrl_change(); app->force_redraw(); } else { if(app->m_ctrls.in_rect(app->m_specific->m_cur_x, app->m_specific->m_cur_y)) { if(app->m_ctrls.set_cur(app->m_specific->m_cur_x, app->m_specific->m_cur_y)) { app->on_ctrl_change(); app->force_redraw(); } } else { app->on_mouse_button_down(app->m_specific->m_cur_x, app->m_specific->m_cur_y, app->m_specific->m_input_flags); } } return CallNextEventHandler (nextHandler, theEvent); } //------------------------------------------------------------------------ pascal OSStatus DoMouseUp (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData) { Point wheresMyMouse; UInt32 modifier; GetEventParameter (theEvent, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &wheresMyMouse); GlobalToLocal (&wheresMyMouse); GetEventParameter (theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifier); platform_support * app = reinterpret_cast(userData); app->m_specific->m_cur_x = wheresMyMouse.h; if(app->flip_y()) { app->m_specific->m_cur_y = app->rbuf_window().height() - wheresMyMouse.v; } else { app->m_specific->m_cur_y = wheresMyMouse.v; } app->m_specific->m_input_flags = mouse_left | get_key_flags(modifier); if(app->m_ctrls.on_mouse_button_up(app->m_specific->m_cur_x, app->m_specific->m_cur_y)) { app->on_ctrl_change(); app->force_redraw(); } app->on_mouse_button_up(app->m_specific->m_cur_x, app->m_specific->m_cur_y, app->m_specific->m_input_flags); return CallNextEventHandler (nextHandler, theEvent); } //------------------------------------------------------------------------ pascal OSStatus DoMouseDragged (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData) { Point wheresMyMouse; UInt32 modifier; GetEventParameter (theEvent, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &wheresMyMouse); GlobalToLocal (&wheresMyMouse); GetEventParameter (theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifier); platform_support * app = reinterpret_cast(userData); app->m_specific->m_cur_x = wheresMyMouse.h; if(app->flip_y()) { app->m_specific->m_cur_y = app->rbuf_window().height() - wheresMyMouse.v; } else { app->m_specific->m_cur_y = wheresMyMouse.v; } app->m_specific->m_input_flags = mouse_left | get_key_flags(modifier); if(app->m_ctrls.on_mouse_move( app->m_specific->m_cur_x, app->m_specific->m_cur_y, (app->m_specific->m_input_flags & mouse_left) != 0)) { app->on_ctrl_change(); app->force_redraw(); } else { app->on_mouse_move(app->m_specific->m_cur_x, app->m_specific->m_cur_y, app->m_specific->m_input_flags); } return CallNextEventHandler (nextHandler, theEvent); } //------------------------------------------------------------------------ pascal OSStatus DoKeyDown (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData) { char key_code; UInt32 modifier; GetEventParameter (theEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &key_code); GetEventParameter (theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifier); platform_support * app = reinterpret_cast(userData); app->m_specific->m_last_translated_key = 0; switch(modifier) { case controlKey: app->m_specific->m_input_flags |= kbd_ctrl; break; case shiftKey: app->m_specific->m_input_flags |= kbd_shift; break; default: app->m_specific->translate(key_code); break; } if(app->m_specific->m_last_translated_key) { bool left = false; bool up = false; bool right = false; bool down = false; switch(app->m_specific->m_last_translated_key) { case key_left: left = true; break; case key_up: up = true; break; case key_right: right = true; break; case key_down: down = true; break; //On a Mac, screenshots are handled by the system. case key_f2: app->copy_window_to_img(agg::platform_support::max_images - 1); app->save_img(agg::platform_support::max_images - 1, "screenshot"); break; } if(app->m_ctrls.on_arrow_keys(left, right, down, up)) { app->on_ctrl_change(); app->force_redraw(); } else { app->on_key(app->m_specific->m_cur_x, app->m_specific->m_cur_y, app->m_specific->m_last_translated_key, app->m_specific->m_input_flags); } } return CallNextEventHandler (nextHandler, theEvent); } //------------------------------------------------------------------------ pascal OSStatus DoKeyUp (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData) { char key_code; UInt32 modifier; GetEventParameter (theEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &key_code); GetEventParameter (theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifier); platform_support * app = reinterpret_cast(userData); app->m_specific->m_last_translated_key = 0; switch(modifier) { case controlKey: app->m_specific->m_input_flags &= ~kbd_ctrl; break; case shiftKey: app->m_specific->m_input_flags &= ~kbd_shift; break; } return CallNextEventHandler (nextHandler, theEvent); } //------------------------------------------------------------------------ pascal OSStatus DoWindowDrawContent (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData) { platform_support * app = reinterpret_cast(userData); if(app) { if(app->m_specific->m_redraw_flag) { app->on_draw(); app->m_specific->m_redraw_flag = false; } app->m_specific->display_pmap(app->m_specific->m_window, &app->rbuf_window()); } return CallNextEventHandler (nextHandler, theEvent); } //------------------------------------------------------------------------ pascal void DoPeriodicTask (EventLoopTimerRef theTimer, void* userData) { platform_support * app = reinterpret_cast(userData); if(!app->wait_mode()) app->on_idle(); } } //---------------------------------------------------------------------------- int agg_main(int argc, char* argv[]); // Hm. Classic MacOS does not know command line input. // CodeWarrior provides a way to mimic command line input. // The function 'ccommand' can be used to get the command // line arguments. //---------------------------------------------------------------------------- int main(int argc, char* argv[]) { #if defined(__MWERKS__) // argc = ccommand (&argv); #endif return agg_main(argc, argv); } aggdraw-1.3.14/agg2/src/platform/sdl/000077500000000000000000000000001417726601400172415ustar00rootroot00000000000000aggdraw-1.3.14/agg2/src/platform/sdl/agg_platform_support.cpp000066400000000000000000000517611417726601400242150ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // class platform_support. SDL version. // //---------------------------------------------------------------------------- #include #include "platform/agg_platform_support.h" #include "SDL.h" namespace agg { //------------------------------------------------------------------------ class platform_specific { public: platform_specific(pix_format_e format, bool flip_y); ~platform_specific(); pix_format_e m_format; pix_format_e m_sys_format; bool m_flip_y; unsigned m_bpp; unsigned m_sys_bpp; unsigned m_rmask; unsigned m_gmask; unsigned m_bmask; unsigned m_amask; bool m_update_flag; bool m_resize_flag; bool m_initialized; SDL_Surface* m_surf_screen; SDL_Surface* m_surf_window; SDL_Surface* m_surf_img[platform_support::max_images]; int m_cur_x; int m_cur_y; int m_sw_start; }; //------------------------------------------------------------------------ platform_specific::platform_specific(pix_format_e format, bool flip_y) : m_format(format), m_sys_format(pix_format_undefined), m_flip_y(flip_y), m_bpp(0), m_sys_bpp(0), m_update_flag(true), m_resize_flag(true), m_initialized(false), m_surf_screen(0), m_surf_window(0), m_cur_x(0), m_cur_y(0) { memset(m_surf_img, 0, sizeof(m_surf_img)); switch(m_format) { case pix_format_gray8: m_bpp = 8; break; case pix_format_rgb565: m_rmask = 0xF800; m_gmask = 0x7E0; m_bmask = 0x1F; m_amask = 0; m_bpp = 16; break; case pix_format_rgb555: m_rmask = 0x7C00; m_gmask = 0x3E0; m_bmask = 0x1F; m_amask = 0; m_bpp = 16; break; case pix_format_rgb24: m_rmask = 0xFF; m_gmask = 0xFF00; m_bmask = 0xFF0000; m_amask = 0; m_bpp = 24; break; case pix_format_bgr24: m_rmask = 0xFF0000; m_gmask = 0xFF00; m_bmask = 0xFF; m_amask = 0; m_bpp = 24; break; case pix_format_bgra32: m_rmask = 0xFF0000; m_gmask = 0xFF00; m_bmask = 0xFF; m_amask = 0xFF000000; m_bpp = 32; break; case pix_format_abgr32: m_rmask = 0xFF000000; m_gmask = 0xFF0000; m_bmask = 0xFF00; m_amask = 0xFF; m_bpp = 32; break; case pix_format_argb32: m_rmask = 0xFF00; m_gmask = 0xFF0000; m_bmask = 0xFF000000; m_amask = 0xFF; m_bpp = 32; break; case pix_format_rgba32: m_rmask = 0xFF; m_gmask = 0xFF00; m_bmask = 0xFF0000; m_amask = 0xFF000000; m_bpp = 32; break; } } //------------------------------------------------------------------------ platform_specific::~platform_specific() { int i; for(i = platform_support::max_images - 1; i >= 0; --i) { if(m_surf_img[i]) SDL_FreeSurface(m_surf_img[i]); } if(m_surf_window) SDL_FreeSurface(m_surf_window); if(m_surf_screen) SDL_FreeSurface(m_surf_screen); } //------------------------------------------------------------------------ platform_support::platform_support(pix_format_e format, bool flip_y) : m_specific(new platform_specific(format, flip_y)), m_format(format), m_bpp(m_specific->m_bpp), m_window_flags(0), m_wait_mode(true), m_flip_y(flip_y) { SDL_Init(SDL_INIT_VIDEO); strcpy(m_caption, "Anti-Grain Geometry Application"); } //------------------------------------------------------------------------ platform_support::~platform_support() { delete m_specific; } //------------------------------------------------------------------------ void platform_support::caption(const char* cap) { strcpy(m_caption, cap); if(m_specific->m_initialized) { SDL_WM_SetCaption(cap, 0); } } //------------------------------------------------------------------------ bool platform_support::init(unsigned width, unsigned height, unsigned flags) { m_window_flags = flags; unsigned wflags = SDL_SWSURFACE; if(m_window_flags & window_hw_buffer) { wflags = SDL_HWSURFACE; } if(m_window_flags & window_resize) { wflags |= SDL_RESIZABLE; } if(m_specific->m_surf_screen) SDL_FreeSurface(m_specific->m_surf_screen); m_specific->m_surf_screen = SDL_SetVideoMode(width, height, m_bpp, wflags); if(m_specific->m_surf_screen == 0) { fprintf(stderr, "Unable to set %dx%d %d bpp video: %s\n", width, height, m_bpp, ::SDL_GetError()); return false; } SDL_WM_SetCaption(m_caption, 0); if(m_specific->m_surf_window) SDL_FreeSurface(m_specific->m_surf_window); m_specific->m_surf_window = SDL_CreateRGBSurface(SDL_HWSURFACE, m_specific->m_surf_screen->w, m_specific->m_surf_screen->h, m_specific->m_surf_screen->format->BitsPerPixel, m_specific->m_rmask, m_specific->m_gmask, m_specific->m_bmask, m_specific->m_amask); if(m_specific->m_surf_window == 0) { fprintf(stderr, "Unable to create image buffer %dx%d %d bpp: %s\n", width, height, m_bpp, SDL_GetError()); return false; } m_rbuf_window.attach((unsigned char*)m_specific->m_surf_window->pixels, m_specific->m_surf_window->w, m_specific->m_surf_window->h, m_flip_y ? -m_specific->m_surf_window->pitch : m_specific->m_surf_window->pitch); if(!m_specific->m_initialized) { m_initial_width = width; m_initial_height = height; on_init(); m_specific->m_initialized = true; } on_resize(m_rbuf_window.width(), m_rbuf_window.height()); m_specific->m_update_flag = true; return true; } //------------------------------------------------------------------------ void platform_support::update_window() { SDL_BlitSurface(m_specific->m_surf_window, 0, m_specific->m_surf_screen, 0); SDL_UpdateRect(m_specific->m_surf_screen, 0, 0, 0, 0); } //------------------------------------------------------------------------ int platform_support::run() { SDL_Event event; bool ev_flag = false; for(;;) { if(m_specific->m_update_flag) { on_draw(); update_window(); m_specific->m_update_flag = false; } ev_flag = false; if(m_wait_mode) { SDL_WaitEvent(&event); ev_flag = true; } else { if(SDL_PollEvent(&event)) { ev_flag = true; } else { on_idle(); } } if(ev_flag) { if(event.type == SDL_QUIT) { break; } int y; unsigned flags = 0; switch (event.type) { case SDL_VIDEORESIZE: if(!init(event.resize.w, event.resize.h, m_window_flags)) return false; on_resize(m_rbuf_window.width(), m_rbuf_window.height()); trans_affine_resizing(event.resize.w, event.resize.h); m_specific->m_update_flag = true; break; case SDL_KEYDOWN: { flags = 0; if(event.key.keysym.mod & KMOD_SHIFT) flags |= kbd_shift; if(event.key.keysym.mod & KMOD_CTRL) flags |= kbd_ctrl; bool left = false; bool up = false; bool right = false; bool down = false; switch(event.key.keysym.sym) { case key_left: left = true; break; case key_up: up = true; break; case key_right: right = true; break; case key_down: down = true; break; } if(m_ctrls.on_arrow_keys(left, right, down, up)) { on_ctrl_change(); force_redraw(); } else { on_key(m_specific->m_cur_x, m_specific->m_cur_y, event.key.keysym.sym, flags); } } break; case SDL_MOUSEMOTION: y = m_flip_y ? m_rbuf_window.height() - event.motion.y : event.motion.y; m_specific->m_cur_x = event.motion.x; m_specific->m_cur_y = y; flags = 0; if(event.motion.state & SDL_BUTTON(1)) flags |= mouse_left; if(event.motion.state & SDL_BUTTON(3)) flags |= mouse_right; if(m_ctrls.on_mouse_move(m_specific->m_cur_x, m_specific->m_cur_y, (flags & mouse_left) != 0)) { on_ctrl_change(); force_redraw(); } else { on_mouse_move(m_specific->m_cur_x, m_specific->m_cur_y, flags); } SDL_Event eventtrash; while (SDL_PeepEvents(&eventtrash, 1, SDL_GETEVENT, SDL_EVENTMASK(SDL_MOUSEMOTION))!=0){;} break; case SDL_MOUSEBUTTONDOWN: y = m_flip_y ? m_rbuf_window.height() - event.motion.y : event.motion.y; m_specific->m_cur_x = event.motion.x; m_specific->m_cur_y = y; flags = 0; if(event.button.button == SDL_BUTTON_LEFT) flags = mouse_left; if(event.button.button == SDL_BUTTON_RIGHT) flags = mouse_right; if(flags & mouse_left) { if(m_ctrls.on_mouse_button_down(m_specific->m_cur_x, m_specific->m_cur_y)) { m_ctrls.set_cur(m_specific->m_cur_x, m_specific->m_cur_y); on_ctrl_change(); force_redraw(); } else { if(m_ctrls.in_rect(m_specific->m_cur_x, m_specific->m_cur_y)) { if(m_ctrls.set_cur(m_specific->m_cur_x, m_specific->m_cur_y)) { on_ctrl_change(); force_redraw(); } } else { on_mouse_button_down(m_specific->m_cur_x, m_specific->m_cur_y, flags); } } } if(flags & mouse_right) { on_mouse_button_down(m_specific->m_cur_x, m_specific->m_cur_y, flags); } break; case SDL_MOUSEBUTTONUP: y = m_flip_y ? m_rbuf_window.height() - event.motion.y : event.motion.y; m_specific->m_cur_x = event.motion.x; m_specific->m_cur_y = y; flags = 0; if(m_ctrls.on_mouse_button_up(m_specific->m_cur_x, m_specific->m_cur_y)) { on_ctrl_change(); force_redraw(); } on_mouse_button_up(m_specific->m_cur_x, m_specific->m_cur_y, flags); break; } } } return 0; } //------------------------------------------------------------------------ const char* platform_support::img_ext() const { return ".bmp"; } //------------------------------------------------------------------------ const char* platform_support::full_file_name(const char* file_name) { return file_name; } //------------------------------------------------------------------------ bool platform_support::load_img(unsigned idx, const char* file) { if(idx < max_images) { if(m_specific->m_surf_img[idx]) SDL_FreeSurface(m_specific->m_surf_img[idx]); char fn[1024]; strcpy(fn, file); int len = strlen(fn); if(len < 4 || strcmp(fn + len - 4, ".bmp") != 0) { strcat(fn, ".bmp"); } SDL_Surface* tmp_surf = SDL_LoadBMP(fn); if (tmp_surf == 0) { fprintf(stderr, "Couldn't load %s: %s\n", fn, SDL_GetError()); return false; } SDL_PixelFormat format; format.palette = 0; format.BitsPerPixel = m_bpp; format.BytesPerPixel = m_bpp >> 8; format.Rmask = m_specific->m_rmask; format.Gmask = m_specific->m_gmask; format.Bmask = m_specific->m_bmask; format.Amask = m_specific->m_amask; format.Rshift = 0; format.Gshift = 0; format.Bshift = 0; format.Ashift = 0; format.Rloss = 0; format.Gloss = 0; format.Bloss = 0; format.Aloss = 0; format.colorkey = 0; format.alpha = 0; m_specific->m_surf_img[idx] = SDL_ConvertSurface(tmp_surf, &format, SDL_SWSURFACE); SDL_FreeSurface(tmp_surf); if(m_specific->m_surf_img[idx] == 0) return false; m_rbuf_img[idx].attach((unsigned char*)m_specific->m_surf_img[idx]->pixels, m_specific->m_surf_img[idx]->w, m_specific->m_surf_img[idx]->h, m_flip_y ? -m_specific->m_surf_img[idx]->pitch : m_specific->m_surf_img[idx]->pitch); return true; } return false; } //------------------------------------------------------------------------ bool platform_support::save_img(unsigned idx, const char* file) { if(idx < max_images && m_specific->m_surf_img[idx]) { char fn[1024]; strcpy(fn, file); int len = strlen(fn); if(len < 4 || strcmp(fn + len - 4, ".bmp") != 0) { strcat(fn, ".bmp"); } return SDL_SaveBMP(m_specific->m_surf_img[idx], fn) == 0; } return false; } //------------------------------------------------------------------------ bool platform_support::create_img(unsigned idx, unsigned width, unsigned height) { if(idx < max_images) { if(m_specific->m_surf_img[idx]) SDL_FreeSurface(m_specific->m_surf_img[idx]); m_specific->m_surf_img[idx] = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, m_specific->m_surf_screen->format->BitsPerPixel, m_specific->m_rmask, m_specific->m_gmask, m_specific->m_bmask, m_specific->m_amask); if(m_specific->m_surf_img[idx] == 0) { fprintf(stderr, "Couldn't create image: %s\n", SDL_GetError()); return false; } m_rbuf_img[idx].attach((unsigned char*)m_specific->m_surf_img[idx]->pixels, m_specific->m_surf_img[idx]->w, m_specific->m_surf_img[idx]->h, m_flip_y ? -m_specific->m_surf_img[idx]->pitch : m_specific->m_surf_img[idx]->pitch); return true; } return false; } //------------------------------------------------------------------------ void platform_support::start_timer() { m_specific->m_sw_start = SDL_GetTicks(); } //------------------------------------------------------------------------ double platform_support::elapsed_time() const { int stop = SDL_GetTicks(); return double(stop - m_specific->m_sw_start); } //------------------------------------------------------------------------ void platform_support::message(const char* msg) { fprintf(stderr, "%s\n", msg); } //------------------------------------------------------------------------ void platform_support::force_redraw() { m_specific->m_update_flag = true; } //------------------------------------------------------------------------ void platform_support::on_init() {} void platform_support::on_resize(int sx, int sy) {} void platform_support::on_idle() {} void platform_support::on_mouse_move(int x, int y, unsigned flags) {} void platform_support::on_mouse_button_down(int x, int y, unsigned flags) {} void platform_support::on_mouse_button_up(int x, int y, unsigned flags) {} void platform_support::on_key(int x, int y, unsigned key, unsigned flags) {} void platform_support::on_ctrl_change() {} void platform_support::on_draw() {} void platform_support::on_post_draw(void* raw_handler) {} } int agg_main(int argc, char* argv[]); int main(int argc, char* argv[]) { return agg_main(argc, argv); } aggdraw-1.3.14/agg2/src/platform/win32/000077500000000000000000000000001417726601400174215ustar00rootroot00000000000000aggdraw-1.3.14/agg2/src/platform/win32/agg_platform_support.cpp000066400000000000000000001217121417726601400243670ustar00rootroot00000000000000//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.2 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com //---------------------------------------------------------------------------- // // class platform_support // //---------------------------------------------------------------------------- #include #include #include "platform/agg_platform_support.h" #include "platform/win32/agg_win32_bmp.h" #include "util/agg_color_conv_rgb8.h" namespace agg { //------------------------------------------------------------------------ HINSTANCE g_windows_instance = 0; int g_windows_cmd_show = 0; //------------------------------------------------------------------------ class platform_specific { public: platform_specific(pix_format_e format, bool flip_y); void create_pmap(unsigned width, unsigned height, rendering_buffer* wnd); void display_pmap(HDC dc, const rendering_buffer* src); bool load_pmap(const char* fn, unsigned idx, rendering_buffer* dst); bool save_pmap(const char* fn, unsigned idx, const rendering_buffer* src); unsigned translate(unsigned keycode); pix_format_e m_format; pix_format_e m_sys_format; bool m_flip_y; unsigned m_bpp; unsigned m_sys_bpp; HWND m_hwnd; pixel_map m_pmap_window; pixel_map m_pmap_img[platform_support::max_images]; unsigned m_keymap[256]; unsigned m_last_translated_key; int m_cur_x; int m_cur_y; unsigned m_input_flags; bool m_redraw_flag; HDC m_current_dc; LARGE_INTEGER m_sw_freq; LARGE_INTEGER m_sw_start; }; //------------------------------------------------------------------------ platform_specific::platform_specific(pix_format_e format, bool flip_y) : m_format(format), m_sys_format(pix_format_undefined), m_flip_y(flip_y), m_bpp(0), m_sys_bpp(0), m_hwnd(0), m_last_translated_key(0), m_cur_x(0), m_cur_y(0), m_input_flags(0), m_redraw_flag(true), m_current_dc(0) { memset(m_keymap, 0, sizeof(m_keymap)); m_keymap[VK_PAUSE] = key_pause; m_keymap[VK_CLEAR] = key_clear; m_keymap[VK_NUMPAD0] = key_kp0; m_keymap[VK_NUMPAD1] = key_kp1; m_keymap[VK_NUMPAD2] = key_kp2; m_keymap[VK_NUMPAD3] = key_kp3; m_keymap[VK_NUMPAD4] = key_kp4; m_keymap[VK_NUMPAD5] = key_kp5; m_keymap[VK_NUMPAD6] = key_kp6; m_keymap[VK_NUMPAD7] = key_kp7; m_keymap[VK_NUMPAD8] = key_kp8; m_keymap[VK_NUMPAD9] = key_kp9; m_keymap[VK_DECIMAL] = key_kp_period; m_keymap[VK_DIVIDE] = key_kp_divide; m_keymap[VK_MULTIPLY] = key_kp_multiply; m_keymap[VK_SUBTRACT] = key_kp_minus; m_keymap[VK_ADD] = key_kp_plus; m_keymap[VK_UP] = key_up; m_keymap[VK_DOWN] = key_down; m_keymap[VK_RIGHT] = key_right; m_keymap[VK_LEFT] = key_left; m_keymap[VK_INSERT] = key_insert; m_keymap[VK_DELETE] = key_delete; m_keymap[VK_HOME] = key_home; m_keymap[VK_END] = key_end; m_keymap[VK_PRIOR] = key_page_up; m_keymap[VK_NEXT] = key_page_down; m_keymap[VK_F1] = key_f1; m_keymap[VK_F2] = key_f2; m_keymap[VK_F3] = key_f3; m_keymap[VK_F4] = key_f4; m_keymap[VK_F5] = key_f5; m_keymap[VK_F6] = key_f6; m_keymap[VK_F7] = key_f7; m_keymap[VK_F8] = key_f8; m_keymap[VK_F9] = key_f9; m_keymap[VK_F10] = key_f10; m_keymap[VK_F11] = key_f11; m_keymap[VK_F12] = key_f12; m_keymap[VK_F13] = key_f13; m_keymap[VK_F14] = key_f14; m_keymap[VK_F15] = key_f15; m_keymap[VK_NUMLOCK] = key_numlock; m_keymap[VK_CAPITAL] = key_capslock; m_keymap[VK_SCROLL] = key_scrollock; switch(m_format) { case pix_format_gray8: m_sys_format = pix_format_gray8; m_bpp = 8; m_sys_bpp = 8; break; case pix_format_rgb565: case pix_format_rgb555: m_sys_format = pix_format_rgb555; m_bpp = 16; m_sys_bpp = 16; break; case pix_format_rgb24: case pix_format_bgr24: m_sys_format = pix_format_bgr24; m_bpp = 24; m_sys_bpp = 24; break; case pix_format_bgra32: case pix_format_abgr32: case pix_format_argb32: case pix_format_rgba32: m_sys_format = pix_format_bgra32; m_bpp = 32; m_sys_bpp = 32; break; } ::QueryPerformanceFrequency(&m_sw_freq); ::QueryPerformanceCounter(&m_sw_start); } //------------------------------------------------------------------------ void platform_specific::create_pmap(unsigned width, unsigned height, rendering_buffer* wnd) { m_pmap_window.create(width, height, org_e(m_bpp)); wnd->attach(m_pmap_window.buf(), m_pmap_window.width(), m_pmap_window.height(), m_flip_y ? m_pmap_window.stride() : -m_pmap_window.stride()); } //------------------------------------------------------------------------ void platform_specific::display_pmap(HDC dc, const rendering_buffer* src) { if(m_sys_format == m_format) { m_pmap_window.draw(dc); } else { pixel_map pmap_tmp; pmap_tmp.create(m_pmap_window.width(), m_pmap_window.height(), org_e(m_sys_bpp)); rendering_buffer rbuf_tmp; rbuf_tmp.attach(pmap_tmp.buf(), pmap_tmp.width(), pmap_tmp.height(), m_flip_y ? pmap_tmp.stride() : -pmap_tmp.stride()); switch(m_format) { case pix_format_gray8: return; case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_rgb555()); break; case pix_format_rgb24: color_conv(&rbuf_tmp, src, color_conv_rgb24_to_bgr24()); break; case pix_format_abgr32: color_conv(&rbuf_tmp, src, color_conv_abgr32_to_bgra32()); break; case pix_format_argb32: color_conv(&rbuf_tmp, src, color_conv_argb32_to_bgra32()); break; case pix_format_rgba32: color_conv(&rbuf_tmp, src, color_conv_rgba32_to_bgra32()); break; } pmap_tmp.draw(dc); } } //------------------------------------------------------------------------ bool platform_specific::save_pmap(const char* fn, unsigned idx, const rendering_buffer* src) { if(m_sys_format == m_format) { return m_pmap_img[idx].save_as_bmp(fn); } pixel_map pmap_tmp; pmap_tmp.create(m_pmap_img[idx].width(), m_pmap_img[idx].height(), org_e(m_sys_bpp)); rendering_buffer rbuf_tmp; rbuf_tmp.attach(pmap_tmp.buf(), pmap_tmp.width(), pmap_tmp.height(), m_flip_y ? pmap_tmp.stride() : -pmap_tmp.stride()); switch(m_format) { case pix_format_gray8: return false; case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_rgb555()); break; case pix_format_rgb24: color_conv(&rbuf_tmp, src, color_conv_rgb24_to_bgr24()); break; case pix_format_abgr32: color_conv(&rbuf_tmp, src, color_conv_abgr32_to_bgra32()); break; case pix_format_argb32: color_conv(&rbuf_tmp, src, color_conv_argb32_to_bgra32()); break; case pix_format_rgba32: color_conv(&rbuf_tmp, src, color_conv_rgba32_to_bgra32()); break; } return pmap_tmp.save_as_bmp(fn); } //------------------------------------------------------------------------ bool platform_specific::load_pmap(const char* fn, unsigned idx, rendering_buffer* dst) { pixel_map pmap_tmp; if(!pmap_tmp.load_from_bmp(fn)) return false; rendering_buffer rbuf_tmp; rbuf_tmp.attach(pmap_tmp.buf(), pmap_tmp.width(), pmap_tmp.height(), m_flip_y ? pmap_tmp.stride() : -pmap_tmp.stride()); m_pmap_img[idx].create(pmap_tmp.width(), pmap_tmp.height(), org_e(m_bpp), 0); dst->attach(m_pmap_img[idx].buf(), m_pmap_img[idx].width(), m_pmap_img[idx].height(), m_flip_y ? m_pmap_img[idx].stride() : -m_pmap_img[idx].stride()); switch(m_format) { case pix_format_gray8: return false; break; case pix_format_rgb555: switch(pmap_tmp.bpp()) { case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb555()); break; case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_rgb555()); break; case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb555()); break; } break; case pix_format_rgb565: switch(pmap_tmp.bpp()) { case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb565()); break; case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_rgb565()); break; case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb565()); break; } break; case pix_format_rgb24: switch(pmap_tmp.bpp()) { case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb24()); break; case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_rgb24()); break; case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb24()); break; } break; case pix_format_bgr24: switch(pmap_tmp.bpp()) { case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_bgr24()); break; case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_bgr24()); break; case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_bgr24()); break; } break; case pix_format_abgr32: switch(pmap_tmp.bpp()) { case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_abgr32()); break; case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_abgr32()); break; case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_abgr32()); break; } break; case pix_format_argb32: switch(pmap_tmp.bpp()) { case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_argb32()); break; case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_argb32()); break; case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_argb32()); break; } break; case pix_format_bgra32: switch(pmap_tmp.bpp()) { case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_bgra32()); break; case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_bgra32()); break; case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_bgra32()); break; } break; case pix_format_rgba32: switch(pmap_tmp.bpp()) { case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgba32()); break; case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_rgba32()); break; case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgba32()); break; } break; } return true; } //------------------------------------------------------------------------ unsigned platform_specific::translate(unsigned keycode) { return m_last_translated_key = (keycode > 255) ? 0 : m_keymap[keycode]; } //------------------------------------------------------------------------ platform_support::platform_support(pix_format_e format, bool flip_y) : m_specific(new platform_specific(format, flip_y)), m_format(format), m_bpp(m_specific->m_bpp), m_window_flags(0), m_wait_mode(true), m_flip_y(flip_y), m_initial_width(10), m_initial_height(10) { strcpy(m_caption, "Anti-Grain Geometry Application"); } //------------------------------------------------------------------------ platform_support::~platform_support() { delete m_specific; } //------------------------------------------------------------------------ void platform_support::caption(const char* cap) { strcpy(m_caption, cap); if(m_specific->m_hwnd) { SetWindowText(m_specific->m_hwnd, m_caption); } } //------------------------------------------------------------------------ void platform_support::start_timer() { ::QueryPerformanceCounter(&(m_specific->m_sw_start)); } //------------------------------------------------------------------------ double platform_support::elapsed_time() const { LARGE_INTEGER stop; ::QueryPerformanceCounter(&stop); return double(stop.QuadPart - m_specific->m_sw_start.QuadPart) * 1000.0 / double(m_specific->m_sw_freq.QuadPart); } /* //------------------------------------------------------------------------ static char* unicode_to_ansi(LPCWSTR pszW) { ULONG cbAnsi, cCharacters; char* pszA = 0; if (pszW == 0) { return 0; } cCharacters = wcslen(pszW)+1; cbAnsi = cCharacters * 2; pszA = new char[cbAnsi]; if(::WideCharToMultiByte(CP_ACP, 0, pszW, cCharacters, pszA, cbAnsi, 0, 0) == 0) { delete [] pszA; return 0; } return pszA; } */ //------------------------------------------------------------------------ static unsigned get_key_flags(int wflags) { unsigned flags = 0; if(wflags & MK_LBUTTON) flags |= mouse_left; if(wflags & MK_RBUTTON) flags |= mouse_right; if(wflags & MK_SHIFT) flags |= kbd_shift; if(wflags & MK_CONTROL) flags |= kbd_ctrl; return flags; } void* platform_support::raw_display_handler() { return m_specific->m_current_dc; } //------------------------------------------------------------------------ LRESULT CALLBACK window_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC paintDC; void* user_data = reinterpret_cast(::GetWindowLong(hWnd, GWL_USERDATA)); platform_support* app = 0; if(user_data) { app = reinterpret_cast(user_data); } if(app == 0) { if(msg == WM_DESTROY) { ::PostQuitMessage(0); return 0; } return ::DefWindowProc(hWnd, msg, wParam, lParam); } HDC dc = ::GetDC(app->m_specific->m_hwnd); app->m_specific->m_current_dc = dc; switch(msg) { //-------------------------------------------------------------------- case WM_CREATE: break; //-------------------------------------------------------------------- case WM_SIZE: app->m_specific->create_pmap(LOWORD(lParam), HIWORD(lParam), &app->rbuf_window()); app->trans_affine_resizing(LOWORD(lParam), HIWORD(lParam)); app->on_resize(LOWORD(lParam), HIWORD(lParam)); app->force_redraw(); break; //-------------------------------------------------------------------- case WM_ERASEBKGND: break; //-------------------------------------------------------------------- case WM_LBUTTONDOWN: app->m_specific->m_cur_x = LOWORD(lParam); if(app->flip_y()) { app->m_specific->m_cur_y = app->rbuf_window().height() - HIWORD(lParam); } else { app->m_specific->m_cur_y = HIWORD(lParam); } app->m_specific->m_input_flags = mouse_left | get_key_flags(wParam); app->m_ctrls.set_cur(app->m_specific->m_cur_x, app->m_specific->m_cur_y); if(app->m_ctrls.on_mouse_button_down(app->m_specific->m_cur_x, app->m_specific->m_cur_y)) { app->on_ctrl_change(); app->force_redraw(); } else { if(app->m_ctrls.in_rect(app->m_specific->m_cur_x, app->m_specific->m_cur_y)) { if(app->m_ctrls.set_cur(app->m_specific->m_cur_x, app->m_specific->m_cur_y)) { app->on_ctrl_change(); app->force_redraw(); } } else { app->on_mouse_button_down(app->m_specific->m_cur_x, app->m_specific->m_cur_y, app->m_specific->m_input_flags); } } break; //-------------------------------------------------------------------- case WM_LBUTTONUP: app->m_specific->m_cur_x = LOWORD(lParam); if(app->flip_y()) { app->m_specific->m_cur_y = app->rbuf_window().height() - HIWORD(lParam); } else { app->m_specific->m_cur_y = HIWORD(lParam); } app->m_specific->m_input_flags = mouse_left | get_key_flags(wParam); if(app->m_ctrls.on_mouse_button_up(app->m_specific->m_cur_x, app->m_specific->m_cur_y)) { app->on_ctrl_change(); app->force_redraw(); } app->on_mouse_button_up(app->m_specific->m_cur_x, app->m_specific->m_cur_y, app->m_specific->m_input_flags); break; //-------------------------------------------------------------------- case WM_RBUTTONDOWN: app->m_specific->m_cur_x = LOWORD(lParam); if(app->flip_y()) { app->m_specific->m_cur_y = app->rbuf_window().height() - HIWORD(lParam); } else { app->m_specific->m_cur_y = HIWORD(lParam); } app->m_specific->m_input_flags = mouse_right | get_key_flags(wParam); app->on_mouse_button_down(app->m_specific->m_cur_x, app->m_specific->m_cur_y, app->m_specific->m_input_flags); break; //-------------------------------------------------------------------- case WM_RBUTTONUP: app->m_specific->m_cur_x = LOWORD(lParam); if(app->flip_y()) { app->m_specific->m_cur_y = app->rbuf_window().height() - HIWORD(lParam); } else { app->m_specific->m_cur_y = HIWORD(lParam); } app->m_specific->m_input_flags = mouse_right | get_key_flags(wParam); app->on_mouse_button_up(app->m_specific->m_cur_x, app->m_specific->m_cur_y, app->m_specific->m_input_flags); break; //-------------------------------------------------------------------- case WM_MOUSEMOVE: app->m_specific->m_cur_x = LOWORD(lParam); if(app->flip_y()) { app->m_specific->m_cur_y = app->rbuf_window().height() - HIWORD(lParam); } else { app->m_specific->m_cur_y = HIWORD(lParam); } app->m_specific->m_input_flags = get_key_flags(wParam); if(app->m_ctrls.on_mouse_move( app->m_specific->m_cur_x, app->m_specific->m_cur_y, (app->m_specific->m_input_flags & mouse_left) != 0)) { app->on_ctrl_change(); app->force_redraw(); } else { if(!app->m_ctrls.in_rect(app->m_specific->m_cur_x, app->m_specific->m_cur_y)) { app->on_mouse_move(app->m_specific->m_cur_x, app->m_specific->m_cur_y, app->m_specific->m_input_flags); } } break; //-------------------------------------------------------------------- case WM_SYSKEYDOWN: case WM_KEYDOWN: app->m_specific->m_last_translated_key = 0; switch(wParam) { case VK_CONTROL: app->m_specific->m_input_flags |= kbd_ctrl; break; case VK_SHIFT: app->m_specific->m_input_flags |= kbd_shift; break; default: app->m_specific->translate(wParam); break; } if(app->m_specific->m_last_translated_key) { bool left = false; bool up = false; bool right = false; bool down = false; switch(app->m_specific->m_last_translated_key) { case key_left: left = true; break; case key_up: up = true; break; case key_right: right = true; break; case key_down: down = true; break; case key_f2: app->copy_window_to_img(agg::platform_support::max_images - 1); app->save_img(agg::platform_support::max_images - 1, "screenshot"); break; } if(app->m_ctrls.on_arrow_keys(left, right, down, up)) { app->on_ctrl_change(); app->force_redraw(); } else { app->on_key(app->m_specific->m_cur_x, app->m_specific->m_cur_y, app->m_specific->m_last_translated_key, app->m_specific->m_input_flags); } } break; //-------------------------------------------------------------------- case WM_SYSKEYUP: case WM_KEYUP: app->m_specific->m_last_translated_key = 0; switch(wParam) { case VK_CONTROL: app->m_specific->m_input_flags &= ~kbd_ctrl; break; case VK_SHIFT: app->m_specific->m_input_flags &= ~kbd_shift; break; } break; //-------------------------------------------------------------------- case WM_CHAR: case WM_SYSCHAR: if(app->m_specific->m_last_translated_key == 0) { app->on_key(app->m_specific->m_cur_x, app->m_specific->m_cur_y, wParam, app->m_specific->m_input_flags); } break; //-------------------------------------------------------------------- case WM_PAINT: paintDC = ::BeginPaint(hWnd, &ps); app->m_specific->m_current_dc = paintDC; if(app->m_specific->m_redraw_flag) { app->on_draw(); app->m_specific->m_redraw_flag = false; } app->m_specific->display_pmap(paintDC, &app->rbuf_window()); app->on_post_draw(paintDC); app->m_specific->m_current_dc = 0; ::EndPaint(hWnd, &ps); break; //-------------------------------------------------------------------- case WM_COMMAND: break; //-------------------------------------------------------------------- case WM_DESTROY: ::PostQuitMessage(0); break; //-------------------------------------------------------------------- default: return ::DefWindowProc(hWnd, msg, wParam, lParam); } app->m_specific->m_current_dc = 0; ::ReleaseDC(app->m_specific->m_hwnd, dc); return 0; } //------------------------------------------------------------------------ void platform_support::message(const char* msg) { ::MessageBox(m_specific->m_hwnd, msg, "AGG Message", MB_OK); } //------------------------------------------------------------------------ bool platform_support::init(unsigned width, unsigned height, unsigned flags) { if(m_specific->m_sys_format == pix_format_undefined) { return false; } m_window_flags = flags; int wflags = CS_OWNDC | CS_VREDRAW | CS_HREDRAW; WNDCLASS wc; wc.lpszClassName = "AGGAppClass"; wc.lpfnWndProc = window_proc; wc.style = wflags; wc.hInstance = g_windows_instance; wc.hIcon = LoadIcon(0, IDI_APPLICATION); wc.hCursor = LoadCursor(0, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wc.lpszMenuName = "AGGAppMenu"; wc.cbClsExtra = 0; wc.cbWndExtra = 0; ::RegisterClass(&wc); wflags = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; if(m_window_flags & window_resize) { wflags |= WS_THICKFRAME | WS_MAXIMIZEBOX; } m_specific->m_hwnd = ::CreateWindow("AGGAppClass", m_caption, wflags, 100, 100, width, height, 0, 0, g_windows_instance, 0); if(m_specific->m_hwnd == 0) { return false; } RECT rct; ::GetClientRect(m_specific->m_hwnd, &rct); ::MoveWindow(m_specific->m_hwnd, // handle to window 100, // horizontal position 100, // vertical position width + (width - (rct.right - rct.left)), height + (height - (rct.bottom - rct.top)), FALSE); ::SetWindowLong(m_specific->m_hwnd, GWL_USERDATA, (LONG)this); m_specific->create_pmap(width, height, &m_rbuf_window); m_initial_width = width; m_initial_height = height; on_init(); m_specific->m_redraw_flag = true; ::ShowWindow(m_specific->m_hwnd, g_windows_cmd_show); return true; } //------------------------------------------------------------------------ int platform_support::run() { MSG msg; for(;;) { if(m_wait_mode) { if(!::GetMessage(&msg, 0, 0, 0)) { break; } ::TranslateMessage(&msg); ::DispatchMessage(&msg); } else { if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { ::TranslateMessage(&msg); if(msg.message == WM_QUIT) { break; } ::DispatchMessage(&msg); } else { on_idle(); } } } return (int)msg.wParam; } //------------------------------------------------------------------------ const char* platform_support::img_ext() const { return ".bmp"; } //------------------------------------------------------------------------ const char* platform_support::full_file_name(const char* file_name) { return file_name; } //------------------------------------------------------------------------ bool platform_support::load_img(unsigned idx, const char* file) { if(idx < max_images) { char fn[1024]; strcpy(fn, file); int len = strlen(fn); if(len < 4 || stricmp(fn + len - 4, ".BMP") != 0) { strcat(fn, ".bmp"); } return m_specific->load_pmap(fn, idx, &m_rbuf_img[idx]); } return true; } //------------------------------------------------------------------------ bool platform_support::save_img(unsigned idx, const char* file) { if(idx < max_images) { char fn[1024]; strcpy(fn, file); int len = strlen(fn); if(len < 4 || stricmp(fn + len - 4, ".BMP") != 0) { strcat(fn, ".bmp"); } return m_specific->save_pmap(fn, idx, &m_rbuf_img[idx]); } return true; } //------------------------------------------------------------------------ bool platform_support::create_img(unsigned idx, unsigned width, unsigned height) { if(idx < max_images) { if(width == 0) width = m_specific->m_pmap_window.width(); if(height == 0) height = m_specific->m_pmap_window.height(); m_specific->m_pmap_img[idx].create(width, height, org_e(m_specific->m_bpp)); m_rbuf_img[idx].attach(m_specific->m_pmap_img[idx].buf(), m_specific->m_pmap_img[idx].width(), m_specific->m_pmap_img[idx].height(), m_flip_y ? m_specific->m_pmap_img[idx].stride() : -m_specific->m_pmap_img[idx].stride()); return true; } return false; } //------------------------------------------------------------------------ void platform_support::force_redraw() { m_specific->m_redraw_flag = true; ::InvalidateRect(m_specific->m_hwnd, 0, FALSE); } //------------------------------------------------------------------------ void platform_support::update_window() { HDC dc = ::GetDC(m_specific->m_hwnd); m_specific->display_pmap(dc, &m_rbuf_window); ::ReleaseDC(m_specific->m_hwnd, dc); } //------------------------------------------------------------------------ void platform_support::on_init() {} void platform_support::on_resize(int sx, int sy) {} void platform_support::on_idle() {} void platform_support::on_mouse_move(int x, int y, unsigned flags) {} void platform_support::on_mouse_button_down(int x, int y, unsigned flags) {} void platform_support::on_mouse_button_up(int x, int y, unsigned flags) {} void platform_support::on_key(int x, int y, unsigned key, unsigned flags) {} void platform_support::on_ctrl_change() {} void platform_support::on_draw() {} void platform_support::on_post_draw(void* raw_handler) {} } namespace agg { // That's ridiculous. I have to parse the command line by myself // because Windows doesn't provide a method of getting the command // line arguments in a form of argc, argv. Of course, there's // CommandLineToArgv() but first, it returns Unicode that I don't // need to deal with, but most of all, it's not compatible with Win98. //----------------------------------------------------------------------- class tokenizer { public: enum sep_flag { single, multiple, whole_str }; struct token { const char* ptr; unsigned len; }; public: tokenizer(const char* sep, const char* trim=0, const char* quote="\"", char mask_chr='\\', sep_flag sf=multiple); void set_str(const char* str); token next_token(); private: int check_chr(const char *str, char chr); private: const char* m_src_string; int m_start; const char* m_sep; const char* m_trim; const char* m_quote; char m_mask_chr; unsigned m_sep_len; sep_flag m_sep_flag; }; //----------------------------------------------------------------------- inline void tokenizer::set_str(const char* str) { m_src_string = str; m_start = 0; } //----------------------------------------------------------------------- inline int tokenizer::check_chr(const char *str, char chr) { return int(strchr(str, chr)); } //----------------------------------------------------------------------- tokenizer::tokenizer(const char* sep, const char* trim, const char* quote, char mask_chr, sep_flag sf) : m_src_string(0), m_start(0), m_sep(sep), m_trim(trim), m_quote(quote), m_mask_chr(mask_chr), m_sep_len(sep ? strlen(sep) : 0), m_sep_flag(sep ? sf : single) { } //----------------------------------------------------------------------- tokenizer::token tokenizer::next_token() { unsigned count = 0; char quote_chr = 0; token tok; tok.ptr = 0; tok.len = 0; if(m_src_string == 0 || m_start == -1) return tok; register const char *pstr = m_src_string + m_start; if(*pstr == 0) { m_start = -1; return tok; } int sep_len = 1; if(m_sep_flag == whole_str) sep_len = m_sep_len; if(m_sep_flag == multiple) { //Pass all the separator symbols at the begin of the string while(*pstr && check_chr(m_sep, *pstr)) { ++pstr; ++m_start; } } if(*pstr == 0) { m_start = -1; return tok; } for(count = 0;; ++count) { char c = *pstr; int found = 0; //We are outside of qotation: find one of separator symbols if(quote_chr == 0) { if(sep_len == 1) { found = check_chr(m_sep, c); } else { found = strncmp(m_sep, pstr, m_sep_len) == 0; } } ++pstr; if(c == 0 || found) { if(m_trim) { while(count && check_chr(m_trim, m_src_string[m_start])) { ++m_start; --count; } while(count && check_chr(m_trim, m_src_string[m_start + count - 1])) { --count; } } tok.ptr = m_src_string + m_start; tok.len = count; //Next time it will be the next separator character //But we must check, whether it is NOT the end of the string. m_start += count; if(c) { m_start += sep_len; if(m_sep_flag == multiple) { //Pass all the separator symbols //after the end of the string while(check_chr(m_sep, m_src_string[m_start])) { ++m_start; } } } break; } //Switch quote. If it is not a quote yet, try to check any of //quote symbols. Otherwise quote must be finished with quote_symb if(quote_chr == 0) { if(check_chr(m_quote, c)) { quote_chr = c; continue; } } else { //We are inside quote: pass all the mask symbols if(m_mask_chr && c == m_mask_chr) { if(*pstr) { ++count; ++pstr; } continue; } if(c == quote_chr) { quote_chr = 0; continue; } } } return tok; } } //---------------------------------------------------------------------------- int agg_main(int argc, char* argv[]); //---------------------------------------------------------------------------- int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) { agg::g_windows_instance = hInstance; agg::g_windows_cmd_show = nCmdShow; char* argv_str = new char [strlen(lpszCmdLine) + 3]; char* argv_ptr = argv_str; char* argv[64]; memset(argv, 0, sizeof(argv)); agg::tokenizer cmd_line(" ", "\"' ", "\"'", '\\', agg::tokenizer::multiple); cmd_line.set_str(lpszCmdLine); int argc = 0; argv[argc++] = argv_ptr; *argv_ptr++ = 0; while(argc < 64) { agg::tokenizer::token tok = cmd_line.next_token(); if(tok.ptr == 0) break; if(tok.len) { memcpy(argv_ptr, tok.ptr, tok.len); argv[argc++] = argv_ptr; argv_ptr += tok.len; *argv_ptr++ = 0; } } int ret = agg_main(argc, argv); delete [] argv_str; return ret; } aggdraw-1.3.14/agg2/src/platform/win32/agg_win32_bmp.cpp000066400000000000000000000401201417726601400225400ustar00rootroot00000000000000//---------------------------------------------------------------------------- // //---------------------------------------------------------------------------- // Contact: mcseemagg@yahoo.com //---------------------------------------------------------------------------- // // class pixel_map // //---------------------------------------------------------------------------- #include "platform/win32/agg_win32_bmp.h" #include "agg_basics.h" namespace agg { //------------------------------------------------------------------------ pixel_map::~pixel_map() { destroy(); } //------------------------------------------------------------------------ pixel_map::pixel_map() : m_bmp(0), m_buf(0), m_bpp(0), m_is_internal(false), m_img_size(0), m_full_size(0) { } //------------------------------------------------------------------------ void pixel_map::destroy() { if(m_bmp && m_is_internal) delete [] (unsigned char*)m_bmp; m_bmp = 0; m_is_internal = false; m_buf = 0; } //------------------------------------------------------------------------ void pixel_map::create(unsigned width, unsigned height, org_e org, unsigned clear_val) { destroy(); if(width == 0) width = 1; if(height == 0) height = 1; m_bpp = org; create_from_bmp(create_bitmap_info(width, height, m_bpp)); create_gray_scale_palette(m_bmp); m_is_internal = true; if(clear_val <= 255) { memset(m_buf, clear_val, m_img_size); } } //------------------------------------------------------------------------ void pixel_map::clear(unsigned clear_val) { if(m_buf) memset(m_buf, clear_val, m_img_size); } //------------------------------------------------------------------------ void pixel_map::attach_to_bmp(BITMAPINFO *bmp) { if(bmp) { destroy(); create_from_bmp(bmp); m_is_internal = false; } } //static //------------------------------------------------------------------------ unsigned pixel_map::calc_full_size(BITMAPINFO *bmp) { if(bmp == 0) return 0; return sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * calc_palette_size(bmp) + bmp->bmiHeader.biSizeImage; } //static //------------------------------------------------------------------------ unsigned pixel_map::calc_header_size(BITMAPINFO *bmp) { if(bmp == 0) return 0; return sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * calc_palette_size(bmp); } //static //------------------------------------------------------------------------ unsigned pixel_map::calc_palette_size(unsigned clr_used, unsigned bits_per_pixel) { int palette_size = 0; if(bits_per_pixel <= 8) { palette_size = clr_used; if(palette_size == 0) { palette_size = 1 << bits_per_pixel; } } return palette_size; } //static //------------------------------------------------------------------------ unsigned pixel_map::calc_palette_size(BITMAPINFO *bmp) { if(bmp == 0) return 0; return calc_palette_size(bmp->bmiHeader.biClrUsed, bmp->bmiHeader.biBitCount); } //static //------------------------------------------------------------------------ unsigned char * pixel_map::calc_img_ptr(BITMAPINFO *bmp) { if(bmp == 0) return 0; return ((unsigned char*)bmp) + calc_header_size(bmp); } //static //------------------------------------------------------------------------ BITMAPINFO* pixel_map::create_bitmap_info(unsigned width, unsigned height, unsigned bits_per_pixel) { unsigned line_len = calc_row_len(width, bits_per_pixel); unsigned img_size = line_len * height; unsigned rgb_size = calc_palette_size(0, bits_per_pixel) * sizeof(RGBQUAD); unsigned full_size = sizeof(BITMAPINFOHEADER) + rgb_size + img_size; BITMAPINFO *bmp = (BITMAPINFO *) new unsigned char[full_size]; bmp->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmp->bmiHeader.biWidth = width; bmp->bmiHeader.biHeight = height; bmp->bmiHeader.biPlanes = 1; bmp->bmiHeader.biBitCount = (unsigned short)bits_per_pixel; bmp->bmiHeader.biCompression = 0; bmp->bmiHeader.biSizeImage = img_size; bmp->bmiHeader.biXPelsPerMeter = 0; bmp->bmiHeader.biYPelsPerMeter = 0; bmp->bmiHeader.biClrUsed = 0; bmp->bmiHeader.biClrImportant = 0; return bmp; } //static //------------------------------------------------------------------------ void pixel_map::create_gray_scale_palette(BITMAPINFO *bmp) { if(bmp == 0) return; unsigned rgb_size = calc_palette_size(bmp); RGBQUAD *rgb = (RGBQUAD*)(((unsigned char*)bmp) + sizeof(BITMAPINFOHEADER)); unsigned brightness; unsigned i; for(i = 0; i < rgb_size; i++) { brightness = (255 * i) / (rgb_size - 1); rgb->rgbBlue = rgb->rgbGreen = rgb->rgbRed = (unsigned char)brightness; rgb->rgbReserved = 0; rgb++; } } //static //------------------------------------------------------------------------ unsigned pixel_map::calc_row_len(unsigned width, unsigned bits_per_pixel) { unsigned n = width; unsigned k; switch(bits_per_pixel) { case 1: k = n; n = n >> 3; if(k & 7) n++; break; case 4: k = n; n = n >> 1; if(k & 3) n++; break; case 8: break; case 16: n = n << 1; break; case 24: n = (n << 1) + n; break; case 32: n = n << 2; break; default: n = 0; break; } return ((n + 3) >> 2) << 2; } //------------------------------------------------------------------------ void pixel_map::draw(HDC h_dc, const RECT *device_rect, const RECT *bmp_rect) const { if(m_bmp == 0 || m_buf == 0) return; unsigned bmp_x = 0; unsigned bmp_y = 0; unsigned bmp_width = m_bmp->bmiHeader.biWidth; unsigned bmp_height = m_bmp->bmiHeader.biHeight; unsigned dvc_x = 0; unsigned dvc_y = 0; unsigned dvc_width = m_bmp->bmiHeader.biWidth; unsigned dvc_height = m_bmp->bmiHeader.biHeight; if(bmp_rect) { bmp_x = bmp_rect->left; bmp_y = bmp_rect->top; bmp_width = bmp_rect->right - bmp_rect->left; bmp_height = bmp_rect->bottom - bmp_rect->top; } dvc_x = bmp_x; dvc_x = bmp_x; dvc_width = bmp_width; dvc_height = bmp_height; if(device_rect) { dvc_x = device_rect->left; dvc_y = device_rect->top; dvc_width = device_rect->right - device_rect->left; dvc_height = device_rect->bottom - device_rect->top; } if(dvc_width != bmp_width || dvc_height != bmp_height) { ::SetStretchBltMode(h_dc, COLORONCOLOR); ::StretchDIBits( h_dc, // handle of device context dvc_x, // x-coordinate of upper-left corner of source rect. dvc_y, // y-coordinate of upper-left corner of source rect. dvc_width, // width of source rectangle dvc_height, // height of source rectangle bmp_x, bmp_y, // x, y -coordinates of upper-left corner of dest. rect. bmp_width, // width of destination rectangle bmp_height, // height of destination rectangle m_buf, // address of bitmap bits m_bmp, // address of bitmap data DIB_RGB_COLORS, // usage SRCCOPY // raster operation code ); } else { ::SetDIBitsToDevice( h_dc, // handle to device context dvc_x, // x-coordinate of upper-left corner of dvc_y, // y-coordinate of upper-left corner of dvc_width, // source rectangle width dvc_height, // source rectangle height bmp_x, // x-coordinate of lower-left corner of bmp_y, // y-coordinate of lower-left corner of 0, // first scan line in array bmp_height, // number of scan lines m_buf, // address of array with DIB bits m_bmp, // address of structure with bitmap info. DIB_RGB_COLORS // RGB or palette indexes ); } } //------------------------------------------------------------------------ void pixel_map::draw(HDC h_dc, int x, int y, double scale) const { if(m_bmp == 0 || m_buf == 0) return; unsigned width = unsigned(m_bmp->bmiHeader.biWidth * scale); unsigned height = unsigned(m_bmp->bmiHeader.biHeight * scale); RECT rect; rect.left = x; rect.top = y; rect.right = x + width; rect.bottom = y + height; draw(h_dc, &rect); } //------------------------------------------------------------------------ void pixel_map::blend(HDC h_dc, const RECT *device_rect, const RECT *bmp_rect) const { #if !defined(AGG_BMP_ALPHA_BLEND) draw(h_dc, device_rect, bmp_rect); return; #else if(m_bpp != 32) { draw(h_dc, device_rect, bmp_rect); return; } if(m_bmp == 0 || m_buf == 0) return; unsigned bmp_x = 0; unsigned bmp_y = 0; unsigned bmp_width = m_bmp->bmiHeader.biWidth; unsigned bmp_height = m_bmp->bmiHeader.biHeight; unsigned dvc_x = 0; unsigned dvc_y = 0; unsigned dvc_width = m_bmp->bmiHeader.biWidth; unsigned dvc_height = m_bmp->bmiHeader.biHeight; if(bmp_rect) { bmp_x = bmp_rect->left; bmp_y = bmp_rect->top; bmp_width = bmp_rect->right - bmp_rect->left; bmp_height = bmp_rect->bottom - bmp_rect->top; } dvc_x = bmp_x; dvc_x = bmp_x; dvc_width = bmp_width; dvc_height = bmp_height; if(device_rect) { dvc_x = device_rect->left; dvc_y = device_rect->top; dvc_width = device_rect->right - device_rect->left; dvc_height = device_rect->bottom - device_rect->top; } HDC mem_dc = ::CreateCompatibleDC(h_dc); void* buf = 0; HBITMAP bmp = ::CreateDIBSection( mem_dc, m_bmp, DIB_RGB_COLORS, &buf, 0, 0 ); memcpy(buf, m_buf, m_bmp->bmiHeader.biSizeImage); HBITMAP temp = (HBITMAP)::SelectObject(mem_dc, bmp); BLENDFUNCTION blend; blend.BlendOp = AC_SRC_OVER; blend.BlendFlags = 0; #if defined(AC_SRC_ALPHA) blend.AlphaFormat = AC_SRC_ALPHA; //#elif defined(AC_SRC_NO_PREMULT_ALPHA) // blend.AlphaFormat = AC_SRC_NO_PREMULT_ALPHA; #else #error "No appropriate constant for alpha format. Check version of wingdi.h, There must be AC_SRC_ALPHA or AC_SRC_NO_PREMULT_ALPHA" #endif blend.SourceConstantAlpha = 255; ::AlphaBlend( h_dc, dvc_x, dvc_y, dvc_width, dvc_height, mem_dc, bmp_x, bmp_y, bmp_width, bmp_height, blend ); ::SelectObject(mem_dc, temp); ::DeleteObject(bmp); ::DeleteObject(mem_dc); #endif //defined(AGG_BMP_ALPHA_BLEND) } //------------------------------------------------------------------------ void pixel_map::blend(HDC h_dc, int x, int y, double scale) const { if(m_bmp == 0 || m_buf == 0) return; unsigned width = unsigned(m_bmp->bmiHeader.biWidth * scale); unsigned height = unsigned(m_bmp->bmiHeader.biHeight * scale); RECT rect; rect.left = x; rect.top = y; rect.right = x + width; rect.bottom = y + height; blend(h_dc, &rect); } //------------------------------------------------------------------------ bool pixel_map::load_from_bmp(FILE *fd) { BITMAPFILEHEADER bmf; BITMAPINFO *bmi = 0; unsigned bmp_size; fread(&bmf, sizeof(bmf), 1, fd); if(bmf.bfType != 0x4D42) goto bmperr; bmp_size = bmf.bfSize - sizeof(BITMAPFILEHEADER); bmi = (BITMAPINFO*) new unsigned char [bmp_size]; if(fread(bmi, 1, bmp_size, fd) != bmp_size) goto bmperr; destroy(); m_bpp = bmi->bmiHeader.biBitCount; create_from_bmp(bmi); m_is_internal = 1; return true; bmperr: if(bmi) delete [] (unsigned char*) bmi; return false; } //------------------------------------------------------------------------ bool pixel_map::load_from_bmp(const char *filename) { FILE *fd = fopen(filename, "rb"); bool ret = false; if(fd) { ret = load_from_bmp(fd); fclose(fd); } return ret; } //------------------------------------------------------------------------ bool pixel_map::save_as_bmp(FILE *fd) const { if(m_bmp == 0) return 0; BITMAPFILEHEADER bmf; bmf.bfType = 0x4D42; bmf.bfOffBits = calc_header_size(m_bmp) + sizeof(bmf); bmf.bfSize = bmf.bfOffBits + m_img_size; bmf.bfReserved1 = 0; bmf.bfReserved2 = 0; fwrite(&bmf, sizeof(bmf), 1, fd); fwrite(m_bmp, m_full_size, 1, fd); return true; } //------------------------------------------------------------------------ bool pixel_map::save_as_bmp(const char *filename) const { FILE *fd = fopen(filename, "wb"); bool ret = false; if(fd) { ret = save_as_bmp(fd); fclose(fd); } return ret; } //------------------------------------------------------------------------ unsigned char* pixel_map::buf() { return m_buf; } //------------------------------------------------------------------------ unsigned pixel_map::width() const { return m_bmp->bmiHeader.biWidth; } //------------------------------------------------------------------------ unsigned pixel_map::height() const { return m_bmp->bmiHeader.biHeight; } //------------------------------------------------------------------------ int pixel_map::stride() const { return calc_row_len(m_bmp->bmiHeader.biWidth, m_bmp->bmiHeader.biBitCount); } //private //------------------------------------------------------------------------ void pixel_map::create_from_bmp(BITMAPINFO *bmp) { if(bmp) { m_img_size = calc_row_len(bmp->bmiHeader.biWidth, bmp->bmiHeader.biBitCount) * bmp->bmiHeader.biHeight; m_full_size = calc_full_size(bmp); m_bmp = bmp; m_buf = calc_img_ptr(bmp); } } } aggdraw-1.3.14/aggdraw.cxx000066400000000000000000002426431417726601400153770ustar00rootroot00000000000000/* * AGG Draw Library * * WCK-style drawing using the AGG library. * * history: * 2004-09-14 fl created, based on experimental code * 2004-09-15 fl added pen/brush objects (from ironpil), multiple modes * 2004-09-16 fl added text, arc/ellipse support * 2005-03-25 fl added BGRA support * 2005-05-02 fl added (experimental) symbol support * 2005-05-12 fl added image constructor and flush method * 2005-05-18 fl fixed possible image constructor crash * 2005-05-18 fl make sure to keep a reference to the image * 2005-05-19 fl improved symbol path support * 2005-06-12 fl added support for S and T path operators * 2005-06-15 fl added support for outline fonts * 2005-06-15 fl support settransform for basic primitives and text * 2005-06-19 fl use ImageColor.getrgb to resolve colors * 2005-06-30 fl added Path object (stub) * 2005-07-04 fl added Path methods (moveto, lineto, etc) * 2005-07-05 fl added Path support to the line and polygon primitives * 2005-08-10 fl fixed Draw(im) buffer memory leak (ouch!) * 2005-08-20 fl fixed background color setting for RGB modes * 2005-08-30 fl expand polygons by 0.5 pixels by default (experimental) * 2005-08-30 fl fixed proper clipping in rasterizer * 2005-09-23 fl added antialias setting * 2005-09-24 fl don't recreate draw adaptor for each operation * 2005-09-26 fl added coords method to Path type * 2005-10-10 fl fixed broken add_path calls in symbol renderer (1.1) * 2005-10-19 fl added native Windows support (via the Dib factory) * 2005-10-20 fl added clear method * 2005-10-23 fl support either hdc or hwnd in expose * 2006-02-12 fl fixed crashes in type(obj) and path constructor * * Copyright (c) 2003-2006 by Secret Labs AB * * 2015-07-15 ej fixed broken paths * 2017-01-03 ej added support for python 3 * 2017-01-03 ej tostring() -> tobytes(), fromstring() -> frombytes() * 2017-08-18 dh fixed mode to be python str instead of bytes * 2017-08-18 dh fixed a couple compiler warnings (specifically clang) * 2018-04-21 dh fixed python 2 compatibility in getcolor * * Copyright (c) 2011-2017 by AggDraw Developers * */ #define Q(x) #x #define QUOTE(x) Q(x) #if defined(_MSC_VER) #define WINDOWS_LEAN_AND_MEAN #include #endif #ifndef M_PI #define M_PI 3.1415926535897931 #endif #include "Python.h" #if PY_MAJOR_VERSION >= 3 #define IS_PY3K #define HAVE_UNICODE #endif #include "bytesobject.h" #if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x01060000 #if PY_VERSION_HEX < 0x02020000 || defined(Py_USING_UNICODE) /* defining this enables unicode support (default under 1.6a1 and later) */ #define HAVE_UNICODE #endif #endif /* agg2 components */ #include "agg_arc.h" #include "agg_conv_contour.h" #include "agg_conv_curve.h" // #include "agg_conv_dash.h" #include "agg_conv_stroke.h" #include "agg_conv_transform.h" #include "agg_ellipse.h" #if defined(HAVE_FREETYPE2) #include "agg_font_freetype.h" #endif #include "agg_path_storage.h" #include "agg_pixfmt_gray8.h" #include "agg_pixfmt_rgb24.h" #include "agg_pixfmt_rgba32.h" #include "agg_rasterizer_scanline_aa.h" #include "agg_renderer_scanline.h" #include "agg_rendering_buffer.h" #include "agg_scanline_p.h" #include "platform/agg_platform_support.h" // agg::pix_format_* /* -------------------------------------------------------------------- */ /* AGG Drawing Surface */ #if defined(HAVE_FREETYPE2) typedef agg::font_engine_freetype_int32 font_engine_type; typedef agg::font_cache_manager font_manager_type; static font_engine_type font_engine; static font_manager_type font_manager(font_engine); #endif /* forward declaration */ class draw_adaptor_base; template class draw_adaptor; typedef struct { PyObject_HEAD draw_adaptor_base *draw; agg::rendering_buffer* buffer; agg::trans_affine* transform; unsigned char* buffer_data; int mode; // agg::pix_format_* int xsize, ysize; int buffer_size; PyObject* image; PyObject* background; #if defined(WIN32) HDC dc; HBITMAP bitmap; HGDIOBJ old_bitmap; BITMAPINFO info; #endif } DrawObject; #ifndef Py_TYPE #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) #endif /* glue functions (see the init function for details) */ static PyObject* aggdraw_getcolor_obj; static void draw_dealloc(DrawObject* self); #ifdef IS_PY3K static PyObject* draw_getattro(DrawObject* self, PyObject* nameobj); static PyTypeObject DrawType = { PyVarObject_HEAD_INIT(NULL, 0) "Draw", sizeof(DrawObject), 0, /* methods */ (destructor) draw_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash*/ 0, /* tp_call*/ 0, /* tp_str*/ (getattrofunc)draw_getattro, /* tp_getattro */ }; #else static PyObject* draw_getattr(DrawObject* self, char* name); static PyTypeObject DrawType = { PyVarObject_HEAD_INIT(NULL, 0) "Draw", sizeof(DrawObject), 0, /* methods */ (destructor) draw_dealloc, /* tp_dealloc */ (printfunc)0, /* tp_print */ (getattrfunc)draw_getattr, /* tp_getattr */ 0, /* tp_setattr */ }; #endif typedef struct { PyObject_HEAD agg::rgba8 color; float width; } PenObject; static void pen_dealloc(PenObject* self); #ifdef IS_PY3K static PyTypeObject PenType = { PyVarObject_HEAD_INIT(NULL, 0) "Pen", sizeof(PenObject), 0, /* methods */ (destructor) pen_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ }; #else static PyTypeObject PenType = { PyVarObject_HEAD_INIT(NULL, 0) "Pen", sizeof(PenObject), 0, /* methods */ (destructor) pen_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ }; #endif #define Pen_Check(op) ((op) != NULL && Py_TYPE(op) == &PenType) typedef struct { PyObject_HEAD agg::rgba8 color; } BrushObject; static void brush_dealloc(BrushObject* self); #ifdef IS_PY3K static PyTypeObject BrushType = { PyVarObject_HEAD_INIT(NULL, 0) "Brush", sizeof(BrushObject), 0, /* methods */ (destructor) brush_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ }; #else static PyTypeObject BrushType = { PyVarObject_HEAD_INIT(NULL, 0) "Brush", sizeof(BrushObject), 0, /* methods */ (destructor) brush_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ }; #endif #define Brush_Check(op) ((op) != NULL && Py_TYPE(op) == &BrushType) typedef struct { PyObject_HEAD char* filename; float height; agg::rgba8 color; } FontObject; #if defined(HAVE_FREETYPE2) static FT_Face font_load(FontObject* font, bool outline=false); #endif static void font_dealloc(FontObject* self); #ifdef IS_PY3K static PyObject* font_getattro(FontObject* self, PyObject* nameobj); static PyTypeObject FontType = { PyVarObject_HEAD_INIT(NULL, 0) "Font", sizeof(FontObject), 0, /* methods */ (destructor) font_dealloc, /* tp_dealloc */ (printfunc)0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ (reprfunc)0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ (hashfunc)0, /*tp_hash*/ (ternaryfunc)0, /*tp_call*/ (reprfunc)0, /*tp_str*/ (getattrofunc)font_getattro, /* tp_getattro */ }; #else static PyObject* font_getattr(FontObject* self, char* name); static PyTypeObject FontType = { PyVarObject_HEAD_INIT(NULL, 0) "Font", sizeof(FontObject), 0, /* methods */ (destructor) font_dealloc, /* tp_dealloc */ 0, /* tp_print */ (getattrfunc) font_getattr, /* tp_getattr */ 0, /* tp_setattr */ }; #endif #define Font_Check(op) ((op) != NULL && Py_TYPE(op) == &FontType) typedef struct { PyObject_HEAD agg::path_storage* path; } PathObject; static void path_dealloc(PathObject* self); #ifdef IS_PY3K static PyObject* path_getattro(PathObject* self, PyObject* nameobj); static PyTypeObject PathType = { PyVarObject_HEAD_INIT(NULL, 0) "Path", sizeof(PathObject), 0, /* methods */ (destructor) path_dealloc, /* tp_dealloc */ (printfunc)0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ (reprfunc)0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ (hashfunc)0, /*tp_hash*/ (ternaryfunc)0, /*tp_call*/ (reprfunc)0, /*tp_str*/ (getattrofunc)path_getattro, /* tp_getattro */ }; #else static PyObject* path_getattr(PathObject* self, char* name); static PyTypeObject PathType = { PyObject_HEAD_INIT(NULL) 0, "Path", sizeof(PathObject), 0, /* methods */ (destructor) path_dealloc, /* tp_dealloc */ 0, /* tp_print */ (getattrfunc) path_getattr, /* tp_getattr */ 0, /* tp_setattr */ }; #endif #define Path_Check(op) ((op) != NULL && Py_TYPE(op) == &PathType) static agg::rgba8 getcolor(PyObject* color, int opacity=255); /* -------------------------------------------------------------------- */ #if defined(HAVE_FREETYPE2) static int text_getchar(PyObject* string, int index, unsigned long* char_out) { #if defined(HAVE_UNICODE) if (PyUnicode_Check(string)) { Py_UNICODE* p = PyUnicode_AS_UNICODE(string); int size = PyUnicode_GET_SIZE(string); if (index >= size) return 0; *char_out = p[index]; return 1; } #endif if (PyBytes_Check(string)) { unsigned char* p = (unsigned char*) PyBytes_AS_STRING(string); int size = PyBytes_GET_SIZE(string); if (index >= size) return 0; *char_out = (unsigned char) p[index]; return 1; } return 0; } #endif /* This template class is used to automagically instantiate drawing code for all pixel formats used by the library. */ class draw_adaptor_base { public: const char* mode; virtual ~draw_adaptor_base() {}; virtual void setantialias(bool flag) = 0; virtual void draw(agg::path_storage &path, PyObject* obj1, PyObject* obj2=NULL) = 0; virtual void drawtext(float xy[2], PyObject* text, FontObject* font) {}; }; template class draw_adaptor : public draw_adaptor_base { DrawObject* self; typedef agg::renderer_base renderer_base; typedef agg::renderer_scanline_aa_solid renderer_aa; agg::rasterizer_scanline_aa<> rasterizer; agg::scanline_p8 scanline; public: draw_adaptor(DrawObject* self_, const char* mode_) { self = self_; mode = mode_; setantialias(true); rasterizer.clip_box(0,0, self->xsize, self->ysize); } void setantialias(bool flag) { if (flag) rasterizer.gamma(agg::gamma_linear()); else rasterizer.gamma(agg::gamma_threshold(0.5)); }; void draw(agg::path_storage &path, PyObject* obj1, PyObject* obj2=NULL) { PixFmt pf(*self->buffer); renderer_base rb(pf); renderer_aa renderer(rb); agg::path_storage* p; PenObject* pen; if (Pen_Check(obj1)) pen = (PenObject*) obj1; else if (Pen_Check(obj2)) pen = (PenObject*) obj2; else pen = NULL; BrushObject* brush; if (Brush_Check(obj2)) brush = (BrushObject*) obj2; else if (Brush_Check(obj1)) brush = (BrushObject*) obj1; else brush = NULL; if (self->transform) { p = new agg::path_storage(); agg::conv_transform tp(path, *self->transform); p->add_path(tp, 0, false); } else p = &path; if (brush) { /* interior */ agg::conv_contour contour(*p); contour.auto_detect_orientation(true); if (pen) contour.width(pen->width / 2.0); else contour.width(0.5); rasterizer.reset(); rasterizer.add_path(contour); renderer.color(brush->color); agg::render_scanlines(rasterizer, scanline, renderer); } if (pen) { /* outline */ /* FIXME: add path for dashed lines */ agg::conv_stroke stroke(*p); stroke.width(pen->width); rasterizer.reset(); rasterizer.add_path(stroke); renderer.color(pen->color); agg::render_scanlines(rasterizer, scanline, renderer); } if (self->transform) delete p; } #if defined(HAVE_FREETYPE2) void drawtext(float xy[2], PyObject* text, FontObject* font) { PixFmt pf(*self->buffer); renderer_base rb(pf); renderer_aa renderer(rb); typedef agg::conv_curve curve_t; curve_t curves(font_manager.path_adaptor()); bool outline = (self->transform != NULL); FT_Face face = font_load(font, outline); if (!face) return; double x = xy[0]; double y = xy[1] + face->size->metrics.ascender/64.0; renderer.color(font->color); curves.approximation_scale(1); unsigned long ch; int index = 0; while (text_getchar(text, index, &ch)) { const agg::glyph_cache* glyph; glyph = font_manager.glyph(ch); if (!glyph) continue; font_manager.add_kerning(&x, &y); font_manager.init_embedded_adaptors(glyph, x, y); if (outline) { rasterizer.reset(); if (self->transform) { agg::conv_transform tp(curves, *self->transform); rasterizer.add_path(tp); } else rasterizer.add_path(curves); agg::render_scanlines(rasterizer, scanline, renderer); } else { agg::render_scanlines( font_manager.gray8_adaptor(), font_manager.gray8_scanline(), renderer ); } x += glyph->advance_x; y += glyph->advance_y; index++; } } #endif }; /* -------------------------------------------------------------------- */ static void clear(DrawObject* self, PyObject* background) { if (background && background != Py_None) { agg::rgba8 ink = getcolor(background); unsigned char* p = self->buffer_data; int c, i; switch (self->mode) { case agg::pix_format_gray8: c = (ink.r*299 + ink.g*587 + ink.b*114) / 1000; memset(self->buffer_data, c, self->buffer_size); break; case agg::pix_format_rgb24: for (i = 0; i < self->buffer_size; i += 3) { p[i+0] = ink.r; p[i+1] = ink.g; p[i+2] = ink.b; } break; case agg::pix_format_bgr24: for (i = 0; i < self->buffer_size; i += 3) { p[i+0] = ink.b; p[i+1] = ink.g; p[i+2] = ink.r; } break; case agg::pix_format_rgba32: for (i = 0; i < self->buffer_size; i += 4) { p[i+0] = ink.r; p[i+1] = ink.g; p[i+2] = ink.b; p[i+3] = ink.a; } break; case agg::pix_format_bgra32: for (i = 0; i < self->buffer_size; i += 4) { p[i+0] = ink.b; p[i+1] = ink.g; p[i+2] = ink.r; p[i+3] = ink.a; } break; } } else memset(self->buffer_data, 255, self->buffer_size); } static void draw_setup(DrawObject* self) { switch (self->mode) { case agg::pix_format_gray8: self->draw = new draw_adaptor(self, "L"); break; case agg::pix_format_rgb24: self->draw = new draw_adaptor(self, "RGB"); break; case agg::pix_format_bgr24: self->draw = new draw_adaptor(self, "BGR"); break; default: self->draw = new draw_adaptor(self, "RGBA"); break; } } const char *draw_doc = "Creates a drawing interface object.\n" "\n" "Parameters\n" "----------\n" "image_or_mode : PIL.Image.Image or str\n" " A PIL Image or a mode string. The following modes\n" " are supported: \"L\", \"RGB\", \"RGBA\", \"BGR\", \"BGRA\".\n" "size : tuple\n" " If a mode string was given, this argument gives the image size\n" " as a 2-element tuple.\n" "color\n" " An optional background color specifier.\n" " If a mode string was given, this is used to initialize the image memory.\n" " If omitted, it defaults to white with full alpha.\n" "\n" "Examples\n" "--------\n" "\n" " >>> d = aggdraw.Draw(im)\n" " >>> d = aggdraw.Draw(\"RGB\", (800, 600), \"white\")\n"; static PyObject* draw_new(PyObject* self_, PyObject* args) { char buffer[10]; int ok; PyObject* image; char* mode; int xsize, ysize; PyObject* background = NULL; if (PyArg_ParseTuple(args, "O:Draw", &image)) { /* get mode (use a local buffer to avoid GC issues) */ PyObject* mode_obj = PyObject_GetAttrString(image, "mode"); if (!mode_obj) return NULL; if (PyBytes_Check(mode_obj)) { strncpy(buffer, PyBytes_AS_STRING(mode_obj), sizeof buffer); buffer[sizeof(buffer)-1] = '\0'; /* to be on the safe side */ mode = buffer; } else if (PyUnicode_Check(mode_obj)) { PyObject* ascii_mode = PyUnicode_AsASCIIString(mode_obj); if (ascii_mode == NULL) { mode = NULL; } else { strncpy(buffer, PyBytes_AsString(ascii_mode), sizeof buffer); buffer[sizeof(buffer)-1] = '\0'; /* to be on the safe side */ mode = buffer; Py_XDECREF(ascii_mode); } } else mode = NULL; Py_DECREF(mode_obj); if (!mode) { PyErr_SetString( PyExc_TypeError, "bad 'mode' attribute (expected string)" ); return NULL; } PyObject* size_obj = PyObject_GetAttrString(image, "size"); if (!size_obj) return NULL; if (PyTuple_Check(size_obj)) ok = PyArg_ParseTuple(size_obj, "ii", &xsize, &ysize); else { PyErr_SetString( PyExc_TypeError, "bad 'size' attribute (expected 2-tuple)" ); ok = 0; } Py_DECREF(size_obj); if (!ok) return NULL; } else { PyErr_Clear(); if (!PyArg_ParseTuple(args, "s(ii)|O:Draw", &mode, &xsize, &ysize, &background)) return NULL; image = NULL; } DrawObject* self = PyObject_NEW(DrawObject, &DrawType); if (self == NULL) return NULL; int stride; if (!strcmp(mode, "L")) { self->mode = agg::pix_format_gray8; stride = xsize; } else if (!strcmp(mode, "RGB")) { self->mode = agg::pix_format_rgb24; stride = xsize * 3; } else if (!strcmp(mode, "BGR")) { self->mode = agg::pix_format_bgr24; stride = xsize * 3; } else if (!strcmp(mode, "RGBA")) { self->mode = agg::pix_format_rgba32; stride = xsize * 4; } else if (!strcmp(mode, "BGRA")) { self->mode = agg::pix_format_bgra32; stride = xsize * 4; } else { PyErr_SetString(PyExc_ValueError, "bad mode"); PyObject_DEL(self); return NULL; } self->buffer_size = ysize * stride; self->buffer_data = new unsigned char[self->buffer_size]; Py_XINCREF(background); self->background = background; clear(self, background); self->buffer = new agg::rendering_buffer( self->buffer_data, xsize, ysize, stride ); self->xsize = xsize; self->ysize = ysize; self->transform = NULL; self->image = image; if (image) { PyObject* buffer = PyObject_CallMethod(image, "tobytes", NULL); if (!buffer) return NULL; /* FIXME: release resources */ if (!PyBytes_Check(buffer)) { PyErr_SetString( PyExc_TypeError, "bad 'tobytes' return value (expected string)" ); Py_DECREF(buffer); return NULL; } char* data = PyBytes_AS_STRING(buffer); int data_size = PyBytes_GET_SIZE(buffer); if (data_size >= self->buffer_size) memcpy(self->buffer_data, data, self->buffer_size); else { PyErr_SetString(PyExc_ValueError, "not enough data"); Py_DECREF(buffer); return NULL; /* FIXME: release resources */ } Py_INCREF(image); /* hang on to this image */ Py_DECREF(buffer); } draw_setup(self); #if defined(WIN32) self->dc = NULL; #endif return (PyObject*) self; } #if defined(WIN32) const char *dib_doc = "Creates a drawing interface object that can be copied to a window.\n" "\n" "This class is only available on Windows platforms.\n" "This object has the same methods as :class:`Draw`,\n" "plus an expose method that copies the contents to a given window.\n" "\n" ".. versionadded:: 1.2\n" "\n" "Parameters\n" "----------\n" "mode : str\n" " A mode string. Currently this must be \"RGB\".\n" "size : tuple\n" " The image size as a 2-element tuple.\n" "color\n" " An optional background color specifier.\n" " If a mode string was given, this is used to initialize the image memory.\n" " If omitted, it defaults to white with full alpha.\n" "\n" "Example\n" "-------\n" "\n" " >>> d = aggdraw.Dib(\"RGB\", (800, 600), \"white\")\n" " >>> # other operations\n" " >>> d.expose(hwnd=window)\n"; static PyObject* draw_dib(PyObject* self_, PyObject* args) { char* mode; int xsize, ysize; PyObject* background = NULL; if (!PyArg_ParseTuple(args, "s(ii)|O:Dib", &mode, &xsize, &ysize, &background)) return NULL; DrawObject* self = PyObject_NEW(DrawObject, &DrawType); if (self == NULL) return NULL; if (strcmp(mode, "RGB")) { PyErr_SetString(PyExc_ValueError, "bad mode"); PyObject_DEL(self); return NULL; } int stride = xsize * 3; self->mode = agg::pix_format_bgr24; memset(&self->info, 0, sizeof(BITMAPINFOHEADER)); self->info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); self->info.bmiHeader.biWidth = xsize; self->info.bmiHeader.biHeight = ysize; self->info.bmiHeader.biPlanes = 1; self->info.bmiHeader.biBitCount = strlen(mode)*8; self->info.bmiHeader.biCompression = BI_RGB; /* Create DIB */ self->dc = CreateCompatibleDC(NULL); if (!self->dc) { /* FIXME: cleanup */ PyErr_NoMemory(); return NULL; } void* bits; self->bitmap = CreateDIBSection( self->dc, &self->info, DIB_RGB_COLORS, &bits, NULL, 0 ); if (!self->bitmap) { /* FIXME: cleanup */ PyErr_NoMemory(); return NULL; } /* Bind the DIB to the device context */ self->old_bitmap = SelectObject(self->dc, self->bitmap); self->buffer_size = ysize * stride; self->buffer_data = (unsigned char*) bits; Py_XINCREF(background); self->background = background; clear(self, background); self->buffer = new agg::rendering_buffer( self->buffer_data, xsize, ysize, -stride ); self->xsize = xsize; self->ysize = ysize; self->transform = NULL; self->image = NULL; draw_setup(self); return (PyObject*) self; } #endif struct PointF { float X; float Y; }; #ifdef IS_PY3K #define GETFLOAT(op) \ (PyLong_Check(op) ? (float) PyLong_AS_LONG((op)) :\ PyFloat_Check(op) ? (float) PyFloat_AS_DOUBLE((op)) :\ (float) PyFloat_AsDouble(op)) #else #define GETFLOAT(op) \ (PyInt_Check(op) ? (float) PyInt_AS_LONG((op)) :\ PyFloat_Check(op) ? (float) PyFloat_AS_DOUBLE((op)) :\ (float) PyFloat_AsDouble(op)) #endif static PointF* getpoints(PyObject* xyIn, int* count) { PointF *xy; int i, n; /* FIXME: use local buffer (provided by caller) for short sequences */ if (!PySequence_Check(xyIn)) { PyErr_SetString(PyExc_TypeError, "argument must be a sequence"); return NULL; } n = PyObject_Length(xyIn); if (PyErr_Occurred()) return NULL; if (n & 1) { PyErr_SetString(PyExc_TypeError, "expected even number of coordinates"); return NULL; } n /= 2; xy = new PointF[n+1]; if (!xy) { PyErr_NoMemory(); *count = -1; return NULL; } if (PyList_Check(xyIn)) for (i = 0; i < n; i++) { xy[i].X = GETFLOAT(PyList_GET_ITEM(xyIn, i+i)); xy[i].Y = GETFLOAT(PyList_GET_ITEM(xyIn, i+i+1)); } else if (PyTuple_Check(xyIn)) for (i = 0; i < n; i++) { xy[i].X = GETFLOAT(PyTuple_GET_ITEM(xyIn, i+i)); xy[i].Y = GETFLOAT(PyTuple_GET_ITEM(xyIn, i+i+1)); } else for (i = 0; i < n; i++) { PyObject *op; op = PySequence_GetItem(xyIn, i+i); xy[i].X = GETFLOAT(op); Py_DECREF(op); op = PySequence_GetItem(xyIn, i+i+1); xy[i].Y = GETFLOAT(op); Py_DECREF(op); } PyErr_Clear(); *count = n; return xy; } static agg::rgba8 getcolor(PyObject* color, int opacity) { #ifdef IS_PY3K if (PyLong_Check(color)) { int ink = PyLong_AsLong(color); return agg::rgba8(ink, ink, ink, opacity); } #else if (PyInt_Check(color)) { int ink = PyInt_AsLong(color); return agg::rgba8(ink, ink, ink, opacity); } #endif char buffer[10]; char* ink = NULL; if (PyUnicode_Check(color)) { PyObject* ascii_color = PyUnicode_AsASCIIString(color); if (ascii_color == NULL) { ink = NULL; } else { strncpy(buffer, PyBytes_AsString(ascii_color), sizeof buffer); buffer[sizeof(buffer)-1] = '\0'; /* to be on the safe side */ ink = buffer; Py_XDECREF(ascii_color); } } else if (PyBytes_Check(color)) { ink = PyBytes_AsString(color); } /* hex colors */ if (ink && ink[0] == '#' && strlen(ink) == 7) { int i = strtol(ink+1, NULL, 16); /* FIXME: rough parsing */ return agg::rgba8((i>>16)&255,(i>>8)&255,i&255,opacity); } int red, green, blue, alpha = opacity; if (PyArg_ParseTuple(color, "iii|i", &red, &green, &blue, &alpha)) return agg::rgba8(red, green, blue, alpha); PyErr_Clear(); /* unknown color: pass it to the Python layer */ if (aggdraw_getcolor_obj) { PyObject* result; result = PyObject_CallFunction(aggdraw_getcolor_obj, "O", color); if (result) { int ok = PyArg_ParseTuple(result, "iii", &red, &green, &blue); Py_DECREF(result); if (ok) return agg::rgba8(red, green, blue, opacity); } PyErr_Clear(); } /* check for well-known color names (HTML) */ if (PyUnicode_Check(color) || PyBytes_Check(color)) { if (!strcmp(ink, "aqua")) return agg::rgba8(0x00,0xFF,0xFF,opacity); if (!strcmp(ink, "black")) return agg::rgba8(0x00,0x00,0x00,opacity); if (!strcmp(ink, "blue")) return agg::rgba8(0x00,0x00,0xFF,opacity); if (!strcmp(ink, "fuchsia")) return agg::rgba8(0xFF,0x00,0xFF,opacity); if (!strcmp(ink, "gray")) return agg::rgba8(0x80,0x80,0x80,opacity); if (!strcmp(ink, "green")) return agg::rgba8(0x00,0x80,0x00,opacity); if (!strcmp(ink, "lime")) return agg::rgba8(0x00,0xFF,0x00,opacity); if (!strcmp(ink, "maroon")) return agg::rgba8(0x80,0x00,0x00,opacity); if (!strcmp(ink, "navy")) return agg::rgba8(0x00,0x00,0x80,opacity); if (!strcmp(ink, "olive")) return agg::rgba8(0x80,0x80,0x00,opacity); if (!strcmp(ink, "purple")) return agg::rgba8(0x80,0x00,0x80,opacity); if (!strcmp(ink, "red")) return agg::rgba8(0xFF,0x00,0x00,opacity); if (!strcmp(ink, "silver")) return agg::rgba8(0xC0,0xC0,0xC0,opacity); if (!strcmp(ink, "teal")) return agg::rgba8(0x00,0x80,0x80,opacity); if (!strcmp(ink, "white")) return agg::rgba8(0xFF,0xFF,0xFF,opacity); if (!strcmp(ink, "yellow")) return agg::rgba8(0xFF,0xFF,0x00,opacity); /* extra colors (used by test2d.py) */ if (!strcmp(ink, "gold")) return agg::rgba8(0xFF,0xD7,0x00,opacity); } /* default to black (FIXME: raise an exception instead?) */ return agg::rgba8(0, 0, 0, opacity); } /* -------------------------------------------------------------------- */ const char *draw_arc_doc = "Draw a arc.\n" "\n" "Parameters\n" "----------\n" "xy : iterable\n" " A 4-element Python sequence (x, y, x, y), with the\n" " upper left corner given first.\n" "start : float\n" " Start angle in degrees.\n" "end : float\n" " End angle in degrees.\n" "pen : Pen, optional\n" " Optional pen object created by the `Pen` factory.\n"; static PyObject* draw_arc(DrawObject* self, PyObject* args) { float x0, y0, x1, y1; float start, end; PyObject* pen = NULL; if (!PyArg_ParseTuple(args, "(ffff)ff|O:arc", &x0, &y0, &x1, &y1, &start, &end, &pen)) return NULL; agg::path_storage path; agg::arc arc( (x1+x0)/2, (y1+y0)/2, (x1-x0)/2, (y1-y0)/2, -start * (float) (M_PI / 180.0), -end * (float) (M_PI / 180.0), false ); arc.approximation_scale(1); path.add_path(arc); self->draw->draw(path, pen); Py_INCREF(Py_None); return Py_None; } const char *draw_chord_doc = "Draw a chord.\n" "\n" "If a brush is given, it is used to fill the chord.\n" "If a pen is given, it is used to draw an outline around the chord.\n" "Either one (or both) can be left out.\n" "\n" "Parameters\n" "----------\n" "xy : iterable\n" " A 4-element Python sequence (x, y, x, y), with the\n" " upper left corner given first.\n" "start : float\n" " Start angle in degrees.\n" "end : float\n" " End angle in degrees.\n" "pen : Pen, optional\n" " Optional pen object created by the `Pen` factory.\n" "brush : Brush, optional\n" " Optional brush object created by the `Brush` factory.\n"; static PyObject* draw_chord(DrawObject* self, PyObject* args) { float x0, y0, x1, y1; float start, end; PyObject* pen = NULL; PyObject* brush = NULL; if (!PyArg_ParseTuple(args, "(ffff)ff|OO:chord", &x0, &y0, &x1, &y1, &start, &end, &pen, &brush)) return NULL; agg::path_storage path; agg::arc arc( (x1+x0)/2, (y1+y0)/2, (x1-x0)/2, (y1-y0)/2, -start * (float) (M_PI / 180.0), -end * (float) (M_PI / 180.0), false ); arc.approximation_scale(1); path.add_path(arc); path.close_polygon(); self->draw->draw(path, pen, brush); Py_INCREF(Py_None); return Py_None; } const char *draw_ellipse_doc = "Draw a ellipse.\n" "\n" "If a brush is given, it is used to fill the ellipse.\n" "If a pen is given, it is used to draw an outline around the ellipse.\n" "Either one (or both) can be left out.\n" "\n" "Parameters\n" "----------\n" "xy : iterable\n" " A 4-element Python sequence (x, y, x, y), with the\n" " upper left corner given first. To draw a circle, make sure the\n" " coordinates form a square.\n" "pen : Pen, optional\n" " Optional pen object created by the `Pen` factory.\n" "brush : Brush, optional\n" " Optional brush object created by the `Brush` factory.\n"; static PyObject* draw_ellipse(DrawObject* self, PyObject* args) { float x0, y0, x1, y1; PyObject* brush = NULL; PyObject* pen = NULL; if (!PyArg_ParseTuple(args, "(ffff)|OO:ellipse", &x0, &y0, &x1, &y1, &brush, &pen)) return NULL; agg::path_storage path; agg::ellipse ellipse((x1+x0)/2, (y1+y0)/2, (x1-x0)/2, (y1-y0)/2, 8); ellipse.approximation_scale(1); path.add_path(ellipse); self->draw->draw(path, pen, brush); Py_INCREF(Py_None); return Py_None; } const char *draw_line_doc = "Draw a line.\n" "\n" "Parameters\n" "----------\n" "xy : iterable\n" " An iterable (x, y, x, y, ...). If more\n" " than two coordinate pairs are given, they are connected in order,\n" " to form a polyline.\n" "pen : Pen\n" " A pen object created by the Pen factory method.\n" "\n" "Examples\n" "--------\n" "\n" " >>> # a cross\n" " >>> pen = aggdraw.Pen(\"red\")\n" " >>> draw.line((x0, y0, x1, y1), pen)\n" " >>> draw.line((x0, y1, x1, y0), pen)\n" "\n" " >>> # a character\n" " >>> draw.line((0, 0, 20, 100, 30, 50, 40, 100, 60, 0), pen)\n"; static PyObject* draw_line(DrawObject* self, PyObject* args) { PyObject* xyIn; PyObject* pen = NULL; if (!PyArg_ParseTuple(args, "O|O:line", &xyIn, &pen)) return NULL; if (Path_Check(xyIn)) { self->draw->draw(*((PathObject*) xyIn)->path, pen); } else { int count; PointF *xy = getpoints(xyIn, &count); if (!xy) return NULL; agg::path_storage path; path.move_to(xy[0].X, xy[0].Y); for (int i = 1; i < count; i++) path.line_to(xy[i].X, xy[i].Y); delete xy; self->draw->draw(path, pen); } Py_INCREF(Py_None); return Py_None; } const char *draw_pieslice_doc = "Draw a pieslice.\n" "\n" "If a brush is given, it is used to fill the pieslice.\n" "If a pen is given, it is used to draw an outline around the pieslice.\n" "Either one (or both) can be left out.\n" "\n" "Parameters\n" "----------\n" "xy : iterable\n" " A 4-element Python sequence (x, y, x, y), with the\n" " upper left corner given first.\n" "start : float\n" " Start angle in degrees.\n" "end : float\n" " End angle in degrees.\n" "pen : Pen, optional\n" " Optional pen object created by the `Pen` factory.\n" "brush : Brush, optional\n" " Optional brush object created by the `Brush` factory.\n"; static PyObject* draw_pieslice(DrawObject* self, PyObject* args) { float x0, y0, x1, y1; float start, end; PyObject* pen = NULL; PyObject* brush = NULL; if (!PyArg_ParseTuple(args, "(ffff)ff|OO:pieslice", &x0, &y0, &x1, &y1, &start, &end, &pen, &brush)) return NULL; float x = (x1+x0)/2; float y = (y1+y0)/2; agg::path_storage path; agg::arc arc( x, y, (x1-x0)/2, (y1-y0)/2, -start * (float) (M_PI / 180.0), -end * (float) (M_PI / 180.0), false ); arc.approximation_scale(1); path.add_path(arc); path.line_to(x, y); path.close_polygon(); self->draw->draw(path, pen, brush); Py_INCREF(Py_None); return Py_None; } const char *draw_polygon_doc = "Draw a polygon.\n" "\n" "If a brush is given, it is used to fill the polygon.\n" "If a pen is given, it is used to draw an outline around the polygon.\n" "Either one (or both) can be left out.\n" "\n" "Parameters\n" "----------\n" "xy : iterable\n" " A Python sequence (x, y, x, y, …).\n" "pen : Pen\n" " Optional pen object created by the `Pen` factory.\n" "brush : Brush\n" " Optional brush object created by the `Brush` factory.\n"; static PyObject* draw_polygon(DrawObject* self, PyObject* args) { PyObject* xyIn; PyObject* brush = NULL; PyObject* pen = NULL; if (!PyArg_ParseTuple(args, "O|OO:polygon", &xyIn, &brush, &pen)) return NULL; if (Path_Check(xyIn)) { self->draw->draw(*((PathObject*) xyIn)->path, pen, brush); } else { int count; PointF *xy = getpoints(xyIn, &count); if (!xy) return NULL; agg::path_storage path; path.move_to(xy[0].X, xy[0].Y); for (int i = 1; i < count; i++) path.line_to(xy[i].X, xy[i].Y); path.close_polygon(); delete xy; self->draw->draw(path, pen, brush); } Py_INCREF(Py_None); return Py_None; } const char *draw_rectangle_doc = "Draw a rectangle.\n" "\n" "If a brush is given, it is used to fill the rectangle.\n" "If a pen is given, it is used to draw an outline around the rectangle.\n" "Either one (or both) can be left out.\n" "\n" "Parameters\n" "----------\n" "xy : iterable\n" " A Python sequence (x, y, x, y, …).\n" "pen : Pen\n" " Optional pen object created by the `Pen` factory.\n" "brush : Brush\n" " Optional brush object created by the `Brush` factory.\n"; static PyObject* draw_rectangle(DrawObject* self, PyObject* args) { float x0, y0, x1, y1; PyObject* brush = NULL; PyObject* pen = NULL; if (!PyArg_ParseTuple(args, "(ffff)|OO:rectangle", &x0, &y0, &x1, &y1, &brush, &pen)) return NULL; agg::path_storage path; path.move_to(x0, y0); path.line_to(x1, y0); path.line_to(x1, y1); path.line_to(x0, y1); path.close_polygon(); self->draw->draw(path, pen, brush); Py_INCREF(Py_None); return Py_None; } const char *draw_path_doc = "Draw the given path.\n" "\n" "If a brush is given, it is used to fill the path.\n" "If a pen is given, it is used to draw an outline around the path.\n" "Either one (or both) can be left out.\n" "\n" "Parameters\n" "----------\n" "path : Path\n" " Path object created by the `Path` factory.\n" "pen : Pen\n" " Optional pen object created by the `Pen` factory.\n" "brush : Brush\n" " Optional brush object created by the `Brush` factory.\n"; static PyObject* draw_path(DrawObject* self, PyObject* args){ PathObject* path; PyObject* brush = NULL; PyObject* pen = NULL; if (!PyArg_ParseTuple(args, "O!|OO:path", &PathType, &path, &brush, &pen)){ return NULL; } //agg::trans_affine_translation transform(xy[i].X,xy[i].Y); //agg::conv_transform // tp(*symbol->path, transform); //agg::path_storage p; //p.add_path(tp, 0, false); self->draw->draw(*path->path, pen, brush); Py_INCREF(Py_None); return Py_None; }; const char *draw_symbol_doc = "Draw a symbol at the given positions (experimental).\n" "\n" "If a brush is given, it is used to fill the symbol.\n" "If a pen is given, it is used to draw an outline around the symbol.\n" "Either one (or both) can be left out.\n" "\n" "Parameters\n" "----------\n" "xy : iterable\n" " A Python sequence (x, y, x, y, …).\n" "symbol : Symbol\n" " Symbol object created by the `Symbol` factory.\n" "pen : Pen\n" " Optional pen object created by the `Pen` factory.\n" "brush : Brush\n" " Optional brush object created by the `Brush` factory.\n"; static PyObject* draw_symbol(DrawObject* self, PyObject* args) { PyObject* xyIn; PathObject* symbol; PyObject* brush = NULL; PyObject* pen = NULL; if (!PyArg_ParseTuple(args, "OO!|OO:symbol", &xyIn, &PathType, &symbol, &brush, &pen)) return NULL; int count; PointF *xy = getpoints(xyIn, &count); if (!xy) return NULL; for (int i = 0; i < count; i++) { agg::trans_affine_translation transform(xy[i].X,xy[i].Y); agg::conv_transform tp(*symbol->path, transform); agg::path_storage p; p.add_path(tp, 0, false); self->draw->draw(p, pen, brush); } delete xy; Py_INCREF(Py_None); return Py_None; } #if defined(HAVE_FREETYPE2) const char *draw_text_doc = "Draws a text string at the given position, using the given font.\n" "\n" "Parameters\n" "----------\n" "xy : tuple\n" " A two element tuple (x, y).\n" "text : str\n" " String to draw.\n" "font : Font\n" " A font object created by the Font factory.\n"; static PyObject* draw_text(DrawObject* self, PyObject* args) { float xy[2]; PyObject* text; FontObject* font; if (!PyArg_ParseTuple(args, "(ff)OO!:text", xy+0, xy+1, &text, &FontType, &font)) return NULL; self->draw->drawtext(xy, text, font); Py_INCREF(Py_None); return Py_None; } #endif #if defined(HAVE_FREETYPE2) const char *draw_textsize_doc = "Draws a text string at the given position, using the given font.\n" "\n" "Parameters\n" "----------\n" "text : str\n" " String to get the drawn size of.\n" "font : Font\n" " A font object created by the Font factory.\n"; static PyObject* draw_textsize(DrawObject* self, PyObject* args) { PyObject* text; FontObject* font; if (!PyArg_ParseTuple(args, "OO!:text", &text, &FontType, &font)) return NULL; FT_Face face = font_load(font); if (!face) { Py_INCREF(Py_None); return Py_None; } int x, i; unsigned long ch; for (x = i = 0; text_getchar(text, i, &ch); i++) { int index = FT_Get_Char_Index(face, ch); if (index) { int error = FT_Load_Glyph(face, index, FT_LOAD_DEFAULT); if (!error) x += face->glyph->metrics.horiAdvance; } } return Py_BuildValue("ff", x/64.0, face->size->metrics.height/64.0); } #endif const char *draw_setantialias_doc = "Control anti-aliasing (experimental).\n" "\n" "Parameters\n" "----------\n" "flag : bool\n" " True to enable anti-aliasing, false to disable.\n"; static PyObject* draw_setantialias(DrawObject* self, PyObject* args) { int i; if (!PyArg_ParseTuple(args, "i:setantialias", &i)) return NULL; self->draw->setantialias(i != 0); Py_INCREF(Py_None); return Py_None; } const char *draw_settransform_doc = "Replace the current drawing transform (experimental).\n" "\n" "Parameters\n" "----------\n" "transform\n" " The new transform. In the current version, this must be either\n" " a (dx, dy) translation tuple, or a PIL-style (a, b, c, d, e, f)\n" " affine transform tuple. If the transform is omitted, it is reset.\n" "\n" "Examples\n" "--------\n" "\n" " >>> draw.settransform((dx, dy))\n"; static PyObject* draw_settransform(DrawObject* self, PyObject* args) { double a=1, b=0, c=0, d=0, e=1, f=0; if (!PyArg_ParseTuple(args, "|(dd):settransform", &c, &f)) { PyErr_Clear(); if (!PyArg_ParseTuple(args, "(dddddd):settransform", &a, &b, &c, &d, &e, &f)) return NULL; } /* PIL order: x=ax+by+c y=dx+ey+f */ /* AGG order: x=ax+cx+e y=bx+dy+f */ agg::trans_affine* transform = new agg::trans_affine(a, d, b, e, c, f); if (!transform) return PyErr_NoMemory(); delete self->transform; self->transform = transform; Py_INCREF(Py_None); return Py_None; } const char *draw_frombytes_doc = "Copies data from a string buffer to the drawing area." "\n" "Parameters\n" "----------\n" "data : bytes\n" " A string containing packed image data, compatible with PIL’s tostring method.\n"; static PyObject* draw_frombytes(DrawObject* self, PyObject* args) { char* data = NULL; int data_size; if (!PyArg_ParseTuple(args, "s#:frombytes", &data, &data_size)) return NULL; if (data_size >= self->buffer_size) memcpy(self->buffer_data, data, self->buffer_size); else { PyErr_SetString(PyExc_ValueError, "not enough data"); return NULL; } Py_INCREF(Py_None); return Py_None; } const char *draw_tobytes_doc = "Copies data from the drawing area to a string.\n" "\n" "Returns\n" "-------\n" "A string containing packed image data, compatible with PIL’s fromstring method.\n"; static PyObject* draw_tobytes(DrawObject* self, PyObject* args) { if (!PyArg_ParseTuple(args, ":tobytes")) return NULL; return PyBytes_FromStringAndSize( (char*) self->buffer_data, self->buffer_size ); } const char *draw_clear_doc = "Clear the image.\n" "\n" "Parameters\n" "----------\n" "color : tuple or str or int\n" " Background color. This can be a color tuple (R, G, B) or (R, G, B, A), \n" " a CSS-style color name, or a color integer (0xaarrggbb).\n"; static PyObject* draw_clear(DrawObject* self, PyObject* args) { PyObject* background = self->background; if (!PyArg_ParseTuple(args, "|O:clear", &background)) return NULL; clear(self, background); Py_INCREF(Py_None); return Py_None; } const char *draw_expose_doc = "Copies the contents of the drawing object to the given window or device context.\n" "\n" "You must provide either a ``hwnd`` or a ``hdc`` keyword argument.\n" "\n" "Parameters\n" "----------\n" "hwnd : int\n" " A HWND handle, cast to an integer.\n" "hdc : int\n" " A HDC handle, cast to an integer.\n"; #if defined(WIN32) static PyObject* draw_expose(DrawObject* self, PyObject* args, PyObject* kw) { static const char* const kwlist[] = { "", "hwnd", "hdc", NULL }; PyObject* sentinel = NULL; int wnd = 0, dc = 0; if (!PyArg_ParseTupleAndKeywords( args, kw, "|Oii:expose", const_cast(kwlist), &sentinel, &wnd, &dc )) return NULL; if (sentinel || (wnd == 0 && dc == 0)) { PyErr_SetString( PyExc_TypeError, "expected 'hdc' or 'hwnd' keyword argument" ); return NULL; } if (!self->dc) { PyErr_SetString(PyExc_TypeError, "cannot expose this object"); return NULL; } HDC hdc; if (wnd) hdc = GetDC((HWND) wnd); else hdc = (HDC) dc; if (!hdc) { PyErr_SetString(PyExc_IOError, "cannot create device context"); return NULL; } BitBlt(hdc, 0, 0, self->xsize, self->ysize, self->dc, 0, 0, SRCCOPY); if (wnd) ReleaseDC((HWND) wnd, hdc); Py_INCREF(Py_None); return Py_None; } #endif const char *draw_flush_doc = "Updates the associated image.\n" "\n" "If the drawing area is attached to a PIL Image object, this method\n" "must be called to make sure that the image updated.\n"; static PyObject* draw_flush(DrawObject* self, PyObject* args) { PyObject* result; if (!PyArg_ParseTuple(args, ":flush")) return NULL; if (!self->image) { Py_INCREF(Py_None); return Py_None; } PyObject* buffer = draw_tobytes(self, args); if (!buffer) return NULL; result = PyObject_CallMethod(self->image, "frombytes", "N", buffer); if (!result) return NULL; Py_DECREF(result); Py_INCREF(self->image); return self->image; } static void draw_dealloc(DrawObject* self) { #if defined(WIN32) if (self->dc) { if (self->bitmap) { SelectObject(self->dc, self->old_bitmap); DeleteObject(self->bitmap); } if (self->dc) DeleteDC(self->dc); } #endif delete self->draw; delete self->buffer; delete [] self->buffer_data; Py_XDECREF(self->background); Py_XDECREF(self->image); PyObject_DEL(self); } static PyMethodDef draw_methods[] = { {"line", (PyCFunction) draw_line, METH_VARARGS, draw_line_doc}, {"polygon", (PyCFunction) draw_polygon, METH_VARARGS, draw_polygon_doc}, {"rectangle", (PyCFunction) draw_rectangle, METH_VARARGS, draw_rectangle_doc}, #if defined(HAVE_FREETYPE2) {"text", (PyCFunction) draw_text, METH_VARARGS, draw_text_doc}, {"textsize", (PyCFunction) draw_textsize, METH_VARARGS, draw_textsize_doc}, #endif {"path", (PyCFunction) draw_path, METH_VARARGS, draw_path_doc}, {"symbol", (PyCFunction) draw_symbol, METH_VARARGS, draw_symbol_doc}, {"arc", (PyCFunction) draw_arc, METH_VARARGS, draw_arc_doc}, {"chord", (PyCFunction) draw_chord, METH_VARARGS, draw_chord_doc}, {"ellipse", (PyCFunction) draw_ellipse, METH_VARARGS, draw_ellipse_doc}, {"pieslice", (PyCFunction) draw_pieslice, METH_VARARGS, draw_pieslice_doc}, {"settransform", (PyCFunction) draw_settransform, METH_VARARGS, draw_settransform_doc}, {"setantialias", (PyCFunction) draw_setantialias, METH_VARARGS, draw_setantialias_doc}, {"flush", (PyCFunction) draw_flush, METH_VARARGS, draw_flush_doc}, #if defined(WIN32) {"expose", (PyCFunction) draw_expose, METH_VARARGS|METH_KEYWORDS, draw_expose_doc}, #endif {"clear", (PyCFunction) draw_clear, METH_VARARGS, draw_clear_doc}, {"frombytes", (PyCFunction) draw_frombytes, METH_VARARGS, draw_frombytes_doc}, {"tobytes", (PyCFunction) draw_tobytes, METH_VARARGS, draw_tobytes_doc}, {NULL, NULL} }; #ifdef IS_PY3K static PyObject* draw_getattro(DrawObject* self, PyObject* nameobj) { if (!PyUnicode_Check(nameobj)) goto generic; if (PyUnicode_CompareWithASCIIString(nameobj, "mode") == 0) return PyUnicode_FromString(self->draw->mode); if (PyUnicode_CompareWithASCIIString(nameobj, "size") == 0) return Py_BuildValue( "(ii)", self->buffer->width(), self->buffer->height() ); generic: return PyObject_GenericGetAttr((PyObject*)self, nameobj); } #else static PyObject* draw_getattr(DrawObject* self, char* name) { if (!strcmp(name, "mode")) return PyBytes_FromString(self->draw->mode); if (!strcmp(name, "size")) return Py_BuildValue( "(ii)", self->buffer->width(), self->buffer->height() ); return Py_FindMethod(draw_methods, (PyObject*) self, name); } #endif /* -------------------------------------------------------------------- */ const char *pen_doc = "Creates a Pen object.\n" "\n" "Parameters\n" "----------\n" "color : tuple or str or int\n" " Pen color. This can be a color tuple (R, G, B) or (R, G, B, A), \n" " a CSS-style color name, or a color integer (0xaarrggbb).\n" "width : int, optional\n" " Pen width. Default 1.\n" "opacity : int, optional\n" " Pen opacity. Default 255.\n"; static PyObject* pen_new(PyObject* self_, PyObject* args, PyObject* kw) { PenObject* self; PyObject* color; float width = 1.0; int opacity = 255; static const char* const kwlist[] = { "color", "width", "opacity", NULL }; if (!PyArg_ParseTupleAndKeywords(args, kw, "O|fi:Pen", const_cast(kwlist), &color, &width, &opacity)) return NULL; self = PyObject_NEW(PenObject, &PenType); if (self == NULL) return NULL; self->color = getcolor(color, opacity); self->width = width; return (PyObject*) self; } static void pen_dealloc(PenObject* self) { PyObject_DEL(self); } /* -------------------------------------------------------------------- */ const char *brush_doc = "Creates a brush object.\n" "\n" "Parameters\n" "----------\n" "color : tuple or str or int\n" " Brush color. This can be a color tuple (R, G, B) or (R, G, B, A), \n" " a CSS-style color name, or a color integer (0xaarrggbb).\n" "opacity : int, optional\n" " Brush opacity. Default 255.\n"; static PyObject* brush_new(PyObject* self_, PyObject* args, PyObject* kw) { BrushObject* self; PyObject* color; int opacity = 255; static const char* const kwlist[] = { "color", "opacity", NULL }; if (!PyArg_ParseTupleAndKeywords(args, kw, "O|i:Brush", const_cast(kwlist), &color, &opacity)) return NULL; self = PyObject_NEW(BrushObject, &BrushType); if (self == NULL) return NULL; self->color = getcolor(color, opacity); return (PyObject*) self; } static void brush_dealloc(BrushObject* self) { PyObject_DEL(self); } /* -------------------------------------------------------------------- */ const char *font_doc = "Create a font object from a truetype font file for use with `text` and `textsize`.\n" "\n" "Parameters\n" "----------\n" "color : tuple or str or int\n" " Font color. This can be a color tuple (R, G, B) or (R, G, B, A), \n" " a CSS-style color name, or a color integer (0xaarrggbb).\n" "file : str\n" " Font source file.\n" "size : int, optional\n" " Font size in pixels. Default 12.\n" "opacity : int, optional\n" " Font opacity. Default 255.\n"; static PyObject* font_new(PyObject* self_, PyObject* args, PyObject* kw) { PyObject* color; char* filename; float size = 12; int opacity = 255; static const char* const kwlist[] = { "color", "file", "size", "opacity", NULL }; if (!PyArg_ParseTupleAndKeywords(args, kw, "Os|fi:Font", const_cast(kwlist), &color, &filename, &size, &opacity)) return NULL; #if defined(HAVE_FREETYPE2) FontObject* self = PyObject_NEW(FontObject, &FontType); if (self == NULL) return NULL; self->color = getcolor(color, opacity); self->filename = new char[strlen(filename)+1]; strcpy(self->filename, filename); self->height = size; if (!font_load(self)) { PyErr_SetString(PyExc_IOError, "cannot load font"); return NULL; } return (PyObject*) self; #else PyErr_SetString(PyExc_IOError, "cannot load font (no text renderer)"); return NULL; #endif } static PyMethodDef font_methods[] = { {NULL, NULL} }; #if defined(HAVE_FREETYPE2) static FT_Face font_load(FontObject* font, bool outline) { if (outline) font_engine.load_font(font->filename, 0, agg::glyph_ren_outline); else font_engine.load_font(font->filename, 0, agg::glyph_ren_native_gray8); font_engine.flip_y(1); font_engine.height(font->height); // requires patch to "agg2\font_freetype\agg_font_freetype.h" // the patch should simply expose the m_cur_face variable return font_engine.m_cur_face; } #endif #ifdef IS_PY3K static PyObject* font_getattro(FontObject* self, PyObject* nameobj) { if (!PyUnicode_Check(nameobj)) goto generic; #if defined(HAVE_FREETYPE2) FT_Face face; if (PyUnicode_CompareWithASCIIString(nameobj, "family") == 0) { face = font_load(self); if (!face) { Py_INCREF(Py_None); return Py_None; } return PyBytes_FromString(face->family_name); } if (PyUnicode_CompareWithASCIIString(nameobj, "style") == 0) { face = font_load(self); if (!face) { Py_INCREF(Py_None); return Py_None; } return PyBytes_FromString(face->style_name); } if (PyUnicode_CompareWithASCIIString(nameobj, "ascent") == 0) { face = font_load(self); if (!face) { Py_INCREF(Py_None); return Py_None; } return PyFloat_FromDouble(face->size->metrics.ascender/64.0); } if (PyUnicode_CompareWithASCIIString(nameobj, "descent") == 0) { face = font_load(self); if (!face) { Py_INCREF(Py_None); return Py_None; } return PyFloat_FromDouble(-face->size->metrics.descender/64.0); } #endif generic: return PyObject_GenericGetAttr((PyObject*)self, nameobj); } #else static PyObject* font_getattr(FontObject* self, char* name) { #if defined(HAVE_FREETYPE2) FT_Face face; if (!strcmp(name, "family")) { face = font_load(self); if (!face) { Py_INCREF(Py_None); return Py_None; } return PyBytes_FromString(face->family_name); } if (!strcmp(name, "style")) { face = font_load(self); if (!face) { Py_INCREF(Py_None); return Py_None; } return PyBytes_FromString(face->style_name); } if (!strcmp(name, "ascent")) { face = font_load(self); if (!face) { Py_INCREF(Py_None); return Py_None; } return PyFloat_FromDouble(face->size->metrics.ascender/64.0); } if (!strcmp(name, "descent")) { face = font_load(self); if (!face) { Py_INCREF(Py_None); return Py_None; } return PyFloat_FromDouble(-face->size->metrics.descender/64.0); } #endif return Py_FindMethod(font_methods, (PyObject*) self, name); } #endif static void font_dealloc(FontObject* self) { delete [] self->filename; PyObject_DEL(self); } /* -------------------------------------------------------------------- */ const char *path_doc = "Path factory (experimental).\n"; static PyObject* path_new(PyObject* self_, PyObject* args) { PyObject* xyIn = NULL; if (!PyArg_ParseTuple(args, "|O:Path", &xyIn)) return NULL; PathObject* self = PyObject_NEW(PathObject, &PathType); if (self == NULL) return NULL; self->path = new agg::path_storage(); if (xyIn) { int count; PointF *xy = getpoints(xyIn, &count); if (!xy) { path_dealloc(self); return NULL; } self->path->move_to(xy[0].X, xy[0].Y); for (int i = 1; i < count; i++) self->path->line_to(xy[i].X, xy[i].Y); delete xy; } return (PyObject*) self; } const char *symbol_doc = "Create a Symbol object for use with :meth:`Draw.symbol`.\n" "\n" "Parameters\n" "----------\n" "path : str\n" " An SVG-style path descriptor. The following operators\n" " are supported: M (move), L (line), H (horizontal line), V (vertical line),\n" " C (cubic bezier), S (smooth cubic bezier), Q (quadratic bezier),\n" " T (smooth quadratic bezier), and Z (close path). Use lower-case\n" " operators for relative coordinates, upper-case for absolute coordinates.\n"; static PyObject* symbol_new(PyObject* self_, PyObject* args) { char* path; float scale = 1.0; if (!PyArg_ParseTuple(args, "s|f:Symbol", &path, &scale)) return NULL; PathObject* self = PyObject_NEW(PathObject, &PathType); if (self == NULL) return NULL; self->path = new agg::path_storage(); char op = 0; char *p, *q, *e; double x, y, x1, y1, x2, y2; bool curve = 0; p = path; e = path + strlen(path); #define COMMA_WSP\ do { while (isspace(*p)) p++; if (*p == ',') p++; } while (0) /* sloppy SVG-style path parser */ while (p < e) { while (isspace(*p)) p++; if (!*p) break; else if (isalpha(*p)) { op = *p++; } else { if (!op) { PyErr_Format( PyExc_ValueError, "no command at start of path" ); return NULL; } COMMA_WSP; } q = p; /* start of arguments */ switch (op) { case 'M': case 'm': x = strtod(p, &p) * scale; COMMA_WSP; y = strtod(p, &p) * scale; if (op == 'm') self->path->rel_to_abs(&x, &y); self->path->move_to(x, y); break; case 'L': case 'l': x = strtod(p, &p) * scale; COMMA_WSP; y = strtod(p, &p) * scale; if (op == 'l') self->path->rel_to_abs(&x, &y); self->path->line_to(x, y); break; case 'h': case 'H': x = strtod(p, &p) * scale; if (self->path->last_vertex(&x2, &y2) > 0) { if (op == 'h') x += x2; self->path->line_to(x, y2); } break; case 'v': case 'V': y = strtod(p, &p) * scale; if (self->path->last_vertex(&x2, &y2) > 0) { if (op == 'v') y += y2; self->path->line_to(x2, y); } break; case 'c': case 'C': /* cubic bezier (postscript-style) */ x1 = strtod(p, &p) * scale; COMMA_WSP; y1 = strtod(p, &p) * scale; COMMA_WSP; x2 = strtod(p, &p) * scale; COMMA_WSP; y2 = strtod(p, &p) * scale; COMMA_WSP; x = strtod(p, &p) * scale; COMMA_WSP; y = strtod(p, &p) * scale; if (op == 'c') { self->path->rel_to_abs(&x1, &y1); self->path->rel_to_abs(&x2, &y2); self->path->rel_to_abs(&x, &y); } self->path->curve4(x1, y1, x2, y2, x, y); curve = true; break; case 's': case 'S': /* smooth cubic bezier (postscript-style) */ x2 = strtod(p, &p) * scale; COMMA_WSP; y2 = strtod(p, &p) * scale; COMMA_WSP; x = strtod(p, &p) * scale; COMMA_WSP; y = strtod(p, &p) * scale; if (op == 's') { self->path->rel_to_abs(&x2, &y2); self->path->rel_to_abs(&x, &y); } if (self->path->last_vertex(&x1, &y1)) { /* find control segment in previous curve */ double x0, y0; if (self->path->prev_vertex(&x0, &y0)) { x1 += x1 - x0; y1 += y1 - y0; self->path->curve4(x1, y1, x2, y2, x, y); } } curve = true; break; case 'q': case 'Q': /* quadratic bezier (truetype-style) */ x1 = strtod(p, &p) * scale; COMMA_WSP; y1 = strtod(p, &p) * scale; COMMA_WSP; x = strtod(p, &p) * scale; COMMA_WSP; y = strtod(p, &p) * scale; if (op == 'q') { self->path->rel_to_abs(&x1, &y1); self->path->rel_to_abs(&x, &y); } self->path->curve3(x1, y1, x, y); curve = true; break; case 't': case 'T': /* smooth quadratic bezier */ x = strtod(p, &p) * scale; COMMA_WSP; y = strtod(p, &p) * scale; if (op == 't') self->path->rel_to_abs(&x, &y); if (self->path->last_vertex(&x1, &y1)) { /* find control segment in previous curve */ double x0, y0; if (self->path->prev_vertex(&x0, &y0)) { x1 += x1 - x0; y1 += y1 - y0; self->path->curve3(x1, y1, x, y); } } curve = true; break; case 'Z': case 'z': p++; self->path->end_poly(); break; default: PyErr_Format( PyExc_ValueError, "unknown path command '%c'", op ); /* FIXME: cleanup */ return NULL; } if (p == q) { PyErr_Format( PyExc_ValueError, "invalid arguments for command '%c'", op ); /* FIXME: cleanup */ return NULL; } } if (curve) { /* expand curves */ agg::path_storage* path = self->path; agg::conv_curve curve(*path); self->path = new agg::path_storage(); self->path->add_path(curve, 0, false); delete path; } return (PyObject*) self; } void expandPaths(PathObject *self) { agg::path_storage* path = self->path; agg::conv_curve curve(*path); self->path = new agg::path_storage(); self->path->add_path(curve, 0, false); delete path; } const char *path_moveto_doc = "Move the path pointer to the given location.\n" "\n" "Parameters\n" "----------\n" "x\n" "y\n"; static PyObject* path_moveto(PathObject* self, PyObject* args) { double x, y; if (!PyArg_ParseTuple(args, "dd:moveto", &x, &y)) return NULL; self->path->move_to(x, y); Py_INCREF(Py_None); return Py_None; } const char *path_rmoveto_doc = "Move the path pointer to the given location, relative to the current position.\n" "\n" "Parameters\n" "----------\n" "x\n" "y\n"; static PyObject* path_rmoveto(PathObject* self, PyObject* args) { double x, y; if (!PyArg_ParseTuple(args, "dd:rmoveto", &x, &y)) return NULL; self->path->rel_to_abs(&x, &y); self->path->move_to(x, y); Py_INCREF(Py_None); return Py_None; } const char *path_lineto_doc = "Adds a line segment to the path.\n" "\n" "Parameters\n" "----------\n" "x\n" "y\n"; static PyObject* path_lineto(PathObject* self, PyObject* args) { double x, y; if (!PyArg_ParseTuple(args, "dd:lineto", &x, &y)) return NULL; self->path->line_to(x, y); Py_INCREF(Py_None); return Py_None; } const char *path_rlineto_doc = "Adds a line segment to the path, using relative coordinates.\n" "\n" "Same as lineto, but the coordinates are relative to the current position.\n" "\n" "Parameters\n" "----------\n" "x\n" "y\n"; static PyObject* path_rlineto(PathObject* self, PyObject* args) { double x, y; if (!PyArg_ParseTuple(args, "dd:rlineto", &x, &y)) return NULL; self->path->rel_to_abs(&x, &y); self->path->line_to(x, y); Py_INCREF(Py_None); return Py_None; } const char *path_curveto_doc = "Adds a line segment to the path.\n" "\n" "Parameters\n" "----------\n" "x1\n" "y1\n" "x2\n" "y2\n" "x\n" "y\n"; static PyObject* path_curveto(PathObject* self, PyObject* args) { double x1, y1, x2, y2, x, y; if (!PyArg_ParseTuple(args, "dddddd:curveto", &x1, &y1, &x2, &y2, &x, &y)) return NULL; self->path->curve4(x1, y1, x2, y2, x, y); expandPaths(self); Py_INCREF(Py_None); return Py_None; } const char *path_rcurveto_doc = "Adds a bezier curve segment to the path, using relative coordinates.\n" "\n" "Same as curveto, but the coordinates are relative to the current position.\n" "\n" "Parameters\n" "----------\n" "x1\n" "y1\n" "x2\n" "y2\n" "x\n" "y\n"; static PyObject* path_rcurveto(PathObject* self, PyObject* args) { double x1, y1, x2, y2, x, y; if (!PyArg_ParseTuple(args, "dddddd:rcurveto", &x1, &y1, &x2, &y2, &x, &y)) return NULL; self->path->rel_to_abs(&x1, &y1); self->path->rel_to_abs(&x2, &y2); self->path->rel_to_abs(&x, &y); self->path->curve4(x1, y1, x2, y2, x, y); Py_INCREF(Py_None); return Py_None; } const char *path_close_doc = "Close the current path."; static PyObject* path_close(PathObject* self, PyObject* args) { if (!PyArg_ParseTuple(args, ":close")) return NULL; self->path->close_polygon(0); /* expand curves */ agg::path_storage* path = self->path; agg::conv_curve curve(*path); self->path = new agg::path_storage(); self->path->add_path(curve, 0, false); delete path; Py_INCREF(Py_None); return Py_None; } static PyObject* path_polygon(PathObject* self, PyObject* args) { PyObject* xyIn; if (!PyArg_ParseTuple(args, "O:polygon", &xyIn)) return NULL; int count; PointF *xy = getpoints(xyIn, &count); if (!xy) return NULL; agg::path_storage path; path.move_to(xy[0].X, xy[0].Y); for (int i = 1; i < count; i++) path.line_to(xy[i].X, xy[i].Y); path.close_polygon(); delete xy; self->path->add_path(path, 0, false); Py_INCREF(Py_None); return Py_None; } const char *path_coords_doc = "Returns the coordinates for this path.\n" "\n" "Curves are flattened before being returned.\n"; static PyObject* path_coords(PathObject* self, PyObject* args) { if (!PyArg_ParseTuple(args, ":coords")) return NULL; agg::conv_curve curve(*self->path); curve.rewind(0); curve.approximation_scale(1); PyObject* list; list = PyList_New(0); if (!list) return NULL; double x, y; unsigned cmd; while (!agg::is_stop(cmd = curve.vertex(&x, &y))) { if (agg::is_vertex(cmd)) { if (PyList_Append(list, PyFloat_FromDouble(x)) < 0) return NULL; if (PyList_Append(list, PyFloat_FromDouble(y)) < 0) return NULL; } } return list; } static void path_dealloc(PathObject* self) { delete self->path; PyObject_DEL(self); } static PyMethodDef path_methods[] = { {"lineto", (PyCFunction) path_lineto, METH_VARARGS, path_lineto_doc}, {"rlineto", (PyCFunction) path_rlineto, METH_VARARGS, path_rlineto_doc}, {"curveto", (PyCFunction) path_curveto, METH_VARARGS, path_curveto_doc}, {"rcurveto", (PyCFunction) path_rcurveto, METH_VARARGS, path_rcurveto_doc}, {"moveto", (PyCFunction) path_moveto, METH_VARARGS, path_moveto_doc}, {"rmoveto", (PyCFunction) path_rmoveto, METH_VARARGS, path_rmoveto_doc}, {"close", (PyCFunction) path_close, METH_VARARGS, path_close_doc}, {"polygon", (PyCFunction) path_polygon, METH_VARARGS}, {"coords", (PyCFunction) path_coords, METH_VARARGS, path_coords_doc}, {NULL, NULL} }; #ifdef IS_PY3K static PyObject* path_getattro(PathObject* self, PyObject* nameobj) { return PyObject_GenericGetAttr((PyObject*)self, nameobj); } #else static PyObject* path_getattr(PathObject* self, char* name) { return Py_FindMethod(path_methods, (PyObject*) self, name); } #endif /* -------------------------------------------------------------------- */ static PyMethodDef aggdraw_functions[] = { {"Pen", (PyCFunction) pen_new, METH_VARARGS|METH_KEYWORDS, pen_doc}, {"Brush", (PyCFunction) brush_new, METH_VARARGS|METH_KEYWORDS, brush_doc}, {"Font", (PyCFunction) font_new, METH_VARARGS|METH_KEYWORDS, font_doc}, {"Symbol", (PyCFunction) symbol_new, METH_VARARGS, symbol_doc}, {"Path", (PyCFunction) path_new, METH_VARARGS, path_doc}, {"Draw", (PyCFunction) draw_new, METH_VARARGS, draw_doc}, #if defined(WIN32) {"Dib", (PyCFunction) draw_dib, METH_VARARGS, dib_doc}, #endif {NULL, NULL} }; const char *mod_doc = "Python interface to the Anti-Grain Graphics Drawing library\n" "\n" "The aggdraw module implements the basic WCK 2D Drawing Interface on top\n" "of `the AGG library `_. This library supports\n" "anti-aliasing and alpha compositing,\n" "but is otherwise fully compatible with the WCK renderer.\n" "\n" "Examples\n" "--------\n" "\n" " >>> # draw cross on top of PIL image\n" " >>> d = aggdraw.Draw(im)\n" " >>> p = aggdraw.Pen(\"black\", 0.5)\n" " >>> d.line((0, 0, 500, 500), p)\n" " >>> d.line((0, 500, 500, 0), p)\n" " >>> d.flush()\n" "\n" " >>> # draw cross on internal image memory\n" " >>> d = aggdraw.Draw(\"RGB\", (320, 200), \"white\")\n" " >>> p = aggdraw.Pen(\"black\", 0.5)\n" " >>> d.line((0, 0, 500, 500), p)\n" " >>> d.line((0, 500, 500, 0), p)\n" " >>> s = d.tostring()\n"; #ifdef IS_PY3K static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, "aggdraw", mod_doc, -1, aggdraw_functions, NULL, NULL, NULL, NULL, }; #endif static PyObject * aggdraw_init(void) { #ifdef IS_PY3K // PyType_Ready(&DrawType); // PyType_Ready(&PathType); // PyType_Ready(&PenType); // PyType_Ready(&BrushType); // PyType_Ready(&FontType); DrawType.tp_methods = draw_methods; FontType.tp_methods = font_methods; PathType.tp_methods = path_methods; PyObject *module = PyModule_Create(&moduledef); PyObject *version = PyUnicode_FromString(QUOTE(VERSION)); PyObject_SetAttrString(module, "VERSION", version); PyObject_SetAttrString(module, "__version__", version); Py_DECREF(version); #else DrawType.ob_type = PathType.ob_type = &PyType_Type; PenType.ob_type = BrushType.ob_type = FontType.ob_type = &PyType_Type; PyObject *module = Py_InitModule3("aggdraw", aggdraw_functions, mod_doc); PyObject *version = PyBytes_FromString(QUOTE(VERSION)); PyObject_SetAttrString(module, "VERSION", version); PyObject_SetAttrString(module, "__version__", version); Py_DECREF(version); #endif if (module == NULL) return NULL; PyObject* g = PyDict_New(); PyDict_SetItemString(g, "__builtins__", PyEval_GetBuiltins()); PyRun_String( "try:\n" " from PIL import ImageColor\n" "except ImportError:\n" " ImageColor = None\n" "def getcolor(v):\n" // FIXME: add caching (?) " return ImageColor.getrgb(v)\n" "", Py_file_input, g, NULL ); aggdraw_getcolor_obj = PyDict_GetItemString(g, "getcolor"); return module; } #ifdef IS_PY3K PyMODINIT_FUNC PyInit_aggdraw(void) { return aggdraw_init(); } #else PyMODINIT_FUNC initaggdraw(void) { aggdraw_init(); } #endif aggdraw-1.3.14/ci/000077500000000000000000000000001417726601400136175ustar00rootroot00000000000000aggdraw-1.3.14/ci/environment.yaml000066400000000000000000000001371417726601400170500ustar00rootroot00000000000000name: test-environment channels: - conda-forge dependencies: - numpy - pillow - pytest aggdraw-1.3.14/doc/000077500000000000000000000000001417726601400137715ustar00rootroot00000000000000aggdraw-1.3.14/doc/Makefile000066400000000000000000000011111417726601400154230ustar00rootroot00000000000000# Minimal makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build SOURCEDIR = source BUILDDIR = _build # Put it first so that "make" without argument is like "make help". help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) .PHONY: help Makefile # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)aggdraw-1.3.14/doc/make.bat000066400000000000000000000013651417726601400154030ustar00rootroot00000000000000@ECHO OFF pushd %~dp0 REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) set SOURCEDIR=source set BUILDDIR=_build if "%1" == "" goto help %SPHINXBUILD% >NUL 2>NUL if errorlevel 9009 ( echo. echo.The 'sphinx-build' command was not found. Make sure you have Sphinx echo.installed, then set the SPHINXBUILD environment variable to point echo.to the full path of the 'sphinx-build' executable. Alternatively you echo.may add the Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from echo.http://sphinx-doc.org/ exit /b 1 ) %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% goto end :help %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% :end popd aggdraw-1.3.14/doc/source/000077500000000000000000000000001417726601400152715ustar00rootroot00000000000000aggdraw-1.3.14/doc/source/conf.py000066400000000000000000000134041417726601400165720ustar00rootroot00000000000000# -*- coding: utf-8 -*- # # Configuration file for the Sphinx documentation builder. # # This file does only contain a selection of the most common options. For a # full list see the documentation: # http://www.sphinx-doc.org/en/master/config # -- Path setup -------------------------------------------------------------- # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # # To generate apidoc modules: # sphinx-apidoc -f -T -o source/api ../aggdraw ../aggdraw/tests import os import sys sys.path.append(os.path.abspath('../../')) # -- Project information ----------------------------------------------------- project = 'aggdraw' copyright = '2018, aggdraw Developers' author = 'aggdraw Developers' # The short X.Y version version = '1.3.8' # The full version, including alpha/beta/rc tags release = '1.3.8' # -- General configuration --------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. # # needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.imgmath', 'sphinx.ext.napoleon', ] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # # source_suffix = ['.rst', '.md'] source_suffix = '.rst' # The master toctree document. master_doc = 'index' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. language = None # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] # The name of the Pygments (syntax highlighting) style to use. pygments_style = None # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # html_theme = 'alabaster' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. # # html_theme_options = {} # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # Custom sidebar templates, must be a dictionary that maps document names # to template names. # # The default sidebars (for documents that don't match any pattern) are # defined by theme itself. Builtin themes are using these templates by # default: ``['localtoc.html', 'relations.html', 'sourcelink.html', # 'searchbox.html']``. # # html_sidebars = {} # -- Options for HTMLHelp output --------------------------------------------- # Output file base name for HTML help builder. htmlhelp_basename = 'aggdrawdoc' # -- Options for LaTeX output ------------------------------------------------ latex_elements = { # The paper size ('letterpaper' or 'a4paper'). # # 'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). # # 'pointsize': '10pt', # Additional stuff for the LaTeX preamble. # # 'preamble': '', # Latex figure (float) alignment # # 'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ (master_doc, 'aggdraw.tex', 'aggdraw Documentation', 'aggdraw Developers', 'manual'), ] # -- Options for manual page output ------------------------------------------ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ (master_doc, 'aggdraw', 'aggdraw Documentation', [author], 1) ] # -- Options for Texinfo output ---------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ (master_doc, 'aggdraw', 'aggdraw Documentation', author, 'aggdraw', 'One line description of project.', 'Miscellaneous'), ] # -- Options for Epub output ------------------------------------------------- # Bibliographic Dublin Core info. epub_title = project # The unique identifier of the text. This can be a ISBN number # or the project homepage. # # epub_identifier = '' # A unique identification for the text. # # epub_uid = '' # A list of files that should not be packed into the epub file. epub_exclude_files = ['search.html'] # -- Extension configuration ------------------------------------------------- # -- Options for intersphinx extension --------------------------------------- # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = {'https://docs.python.org/3/': None} # -- Options for todo extension ---------------------------------------------- # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = Trueaggdraw-1.3.14/doc/source/index.rst000066400000000000000000000021001417726601400171230ustar00rootroot00000000000000AggDraw ======= The AggDraw library provides a python interface on top of `the AGG library `_. The library was originally developed by Fredrik Lundh (effbot), but has since been picked up by various developers. It is currently maintained by the PyTroll developmer group. The official repository can be found on GitHub: https://github.com/pytroll/aggdraw The original documentation by effbot is `still available `_ but may be out of date with the current version of the library. Original examples will be migrated as time is available (pull requests welcome). Installation ============ Aggdraw is available on Linux, OSX, and Windows. It can be installed from PyPI with pip: .. code-block:: bash pip install aggdraw Or from conda with the conda-forge channel: .. code-block:: bash conda install -c conda-forge aggdraw API === .. automodule:: aggdraw :members: :undoc-members: :show-inheritance: Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` aggdraw-1.3.14/selftest.py000066400000000000000000000075511417726601400154370ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # sanity check import pytest def test_module_init(): import aggdraw assert hasattr(aggdraw, 'VERSION') assert isinstance(aggdraw.VERSION, str) assert hasattr(aggdraw, '__version__') assert isinstance(aggdraw.__version__, str) def test_draw(): from aggdraw import Draw from PIL import Image with pytest.raises(AttributeError) as excinfo: Draw("RGB") assert "'str' object has no attribute 'mode'" in str(excinfo.value) draw = Draw("RGB", (800, 600)) assert draw.mode == 'RGB' assert draw.size == (800, 600) draw = Draw("RGB", (800, 600), "white") assert draw.mode == 'RGB' assert draw.size == (800, 600) im = Image.new("RGB", (600, 800)) draw = Draw(im) assert draw.mode == 'RGB' assert draw.size == (600, 800) def test_flush(): from aggdraw import Draw from PIL import Image im = Image.new("RGB", (600, 800)) draw = Draw(im) assert draw.flush().mode == 'RGB' def test_pen(): from aggdraw import Pen Pen("black") Pen("black", 1) Pen("black", 1.5) Pen("black", 1, opacity=128) Pen(0) Pen((0,0,0)) Pen("rgb(0,0,0)") Pen("gold") def test_brush(): from aggdraw import Brush Brush("black") Brush("black", opacity=128) Brush(0) Brush((0, 0, 0)) Brush("rgb(0, 0, 0)") Brush("gold") def test_graphics(): from aggdraw import Draw, Pen, Brush draw = Draw("RGB", (500, 500)) pen = Pen("black") brush = Brush("black") draw.line((50, 50, 100, 100), pen) draw.rectangle((50, 150, 100, 200), pen) draw.rectangle((50, 220, 100, 270), brush) draw.rectangle((50, 290, 100, 340), brush, pen) draw.rectangle((50, 360, 100, 410), pen, brush) draw.ellipse((120, 150, 170, 200), pen) draw.ellipse((120, 220, 170, 270), brush) draw.ellipse((120, 290, 170, 340), brush, pen) draw.ellipse((120, 360, 170, 410), pen, brush) draw.polygon((190+25, 150, 190, 200, 190+50, 200), pen) draw.polygon((190+25, 220, 190, 270, 190+50, 270), brush) draw.polygon((190+25, 290, 190, 340, 190+50, 340), brush, pen) draw.polygon((190+25, 360, 190, 410, 190+50, 410), pen, brush) def test_graphics2(): """See issue #14.""" from aggdraw import Draw, Symbol, Pen from PIL import Image import numpy as np symbol = Symbol("M400 200 L400 400") pen = Pen("red") image = Image.fromarray(np.zeros((800, 600, 3)), mode="RGB") canvas = Draw(image) canvas.symbol((0, 0), symbol, pen) canvas.flush() assert np.asarray(image).sum() == 50800 def test_graphics3(): """See issue #22.""" from aggdraw import Draw, Pen from PIL import Image main = Image.new('RGB', (480, 1024), 'white') d = Draw(main) p = Pen((90,) * 3, 0.5) def test_path(): from aggdraw import Draw, Path Path() Path([0, 0]) Path([0, 0, 0, 0]) p = Path() p.moveto(0, 0) p.lineto(1, 1) assert p.coords() == [0.0, 0.0, 1.0, 1.0] p.curveto(0, 0, 0, 0, 0, 0) p.close() p.coords() assert p.coords() == [0.0, 0.0, 1.0, 1.0, 0.125, 0.125, 0.0, 0.0] draw = Draw("RGB", (800, 600)) draw.line(p) draw.polygon(p) draw.symbol((0, 0), p) def test_symbol(): from aggdraw import Symbol Symbol("M0,0L0,0L0,0L0,0Z") Symbol("M0,0L0,0,0,0,0,0Z", 10) Symbol("M0,0C0,0,0,0,0,0Z") Symbol("M0,0S0,0,0,0,0,0Z") Symbol("m0,0l0,0l0,0l0,0z") Symbol("m0,0l0,0,0,0,0,0z", 10) Symbol("m0,0c0,0,0,0,0,0z") Symbol("m0,0s0,0,0,0,0,0z") def test_transform(): from aggdraw import Draw draw = Draw("RGB", (500, 500)) draw.settransform() draw.settransform((250, 250)) draw.settransform((1, 0, 250, 0, 1, 250)) draw.settransform((2.0, 0.5, 250, 0.5, 2.0, 250)) draw.settransform() if __name__ == "__main__": import sys sys.exit(pytest.main(sys.argv)) aggdraw-1.3.14/setup.py000066400000000000000000000125371417726601400147460ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # # Setup script for aggdraw # # Usage: # # To build in current directory: # $ python setup.py build_ext -i # # To build and install: # $ python setup.py install # from __future__ import print_function import os import sys import subprocess import platform from distutils.sysconfig import get_config_var from distutils.version import LooseVersion try: from setuptools import setup, Extension except ImportError: from distutils.core import setup, Extension VERSION = "1.3.14" SUMMARY = "High quality drawing interface for PIL." DESCRIPTION = """\ The aggdraw module implements the basic WCK 2D Drawing Interface on top of the AGG library. This library provides high-quality drawing, with anti-aliasing and alpha compositing, while being fully compatible with the WCK renderer. """ def is_platform_mac(): return sys.platform == 'darwin' # For mac, ensure extensions are built for macos 10.9 when compiling on a # 10.9 system or above, overriding distuitls behaviour which is to target # the version that python was built for. This may be overridden by setting # MACOSX_DEPLOYMENT_TARGET before calling setup.py if is_platform_mac(): if 'MACOSX_DEPLOYMENT_TARGET' not in os.environ: current_system = LooseVersion(platform.mac_ver()[0]) python_target = LooseVersion(get_config_var('MACOSX_DEPLOYMENT_TARGET')) if python_target < '10.9' and current_system >= '10.9': os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.9' def _get_freetype_config(): print("Trying freetype-config to find freetype library...") try: # pointer to freetype build directory (tweak as necessary) return subprocess.check_output( ['freetype-config', '--prefix']).strip().replace( b'"', b'').decode() except (OSError, subprocess.CalledProcessError): return None def _get_freetype_with_ctypes(): print("Using ctypes to find freetype library...") from ctypes.util import find_library ft_lib_path = find_library('freetype') if ft_lib_path is None: return None if not sys.platform.startswith('linux') and \ not os.path.isfile(ft_lib_path): return None elif not os.path.isfile(ft_lib_path): # try prefix since find_library doesn't give a full path on linux for bdir in (sys.prefix, '/usr', '/usr/local'): lib_path = os.path.join(bdir, 'lib', ft_lib_path) if os.path.isfile(lib_path): return bdir else: # freetype is somewhere on the system, but we don't know where return None ft_lib_path = os.path.dirname(ft_lib_path) lib_path = os.path.realpath(os.path.join(ft_lib_path, '..')) return lib_path def _get_freetype_with_pkgconfig(): print("Trying 'pkgconfig' to find freetype library...") try: import pkgconfig return pkgconfig.variables('freetype2')['prefix'] except (ImportError, KeyError, ValueError): return None FREETYPE_ROOT = os.getenv('AGGDRAW_FREETYPE_ROOT') for func in (_get_freetype_config, _get_freetype_with_ctypes, _get_freetype_with_pkgconfig): if FREETYPE_ROOT is None: FREETYPE_ROOT = func() if FREETYPE_ROOT is None: print("=== freetype not available") else: print("=== freetype found: '{}'".format(FREETYPE_ROOT)) sources = [ # source code currently used by aggdraw # FIXME: link against AGG library instead? "agg2/src/agg_arc.cpp", "agg2/src/agg_bezier_arc.cpp", "agg2/src/agg_curves.cpp", "agg2/src/agg_path_storage.cpp", "agg2/src/agg_rasterizer_scanline_aa.cpp", "agg2/src/agg_trans_affine.cpp", "agg2/src/agg_vcgen_contour.cpp", # "agg2/src/agg_vcgen_dash.cpp", "agg2/src/agg_vcgen_stroke.cpp", ] # define VERSION macro in C++ code, need to quote it defines = [('VERSION', VERSION)] include_dirs = ["agg2/include"] library_dirs = [] libraries = [] if FREETYPE_ROOT: defines.append(("HAVE_FREETYPE2", None)) sources.extend([ "agg2/font_freetype/agg_font_freetype.cpp", ]) include_dirs.append("agg2/font_freetype") include_dirs.append(os.path.join(FREETYPE_ROOT, "include")) include_dirs.append(os.path.join(FREETYPE_ROOT, "include/freetype")) include_dirs.append(os.path.join(FREETYPE_ROOT, "include/freetype2")) library_dirs.append(os.path.join(FREETYPE_ROOT, "lib")) libraries.append("freetype") if sys.platform == "win32": libraries.extend(["kernel32", "user32", "gdi32"]) setup( name="aggdraw", version=VERSION, author="Fredrik Lundh", author_email="fredrik@pythonware.com", classifiers=[ "Development Status :: 4 - Beta", # "Development Status :: 5 - Production/Stable", "Topic :: Multimedia :: Graphics", ], description=SUMMARY, download_url="http://www.effbot.org/downloads#aggdraw", license="Python (MIT style)", long_description=DESCRIPTION.strip(), platforms="Python 2.7 and later.", url="https://github.com/pytroll/aggdraw", ext_modules=[ Extension("aggdraw", ["aggdraw.cxx"] + sources, define_macros=defines, include_dirs=include_dirs, library_dirs=library_dirs, libraries=libraries ) ], python_requires='>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*', tests_require=['pillow', 'pytest'], )