From 5dfd0e4dd1801093af80e4d10cb812221be5975e Mon Sep 17 00:00:00 2001 From: tomo Date: Tue, 9 Mar 2004 05:26:37 +0000 Subject: [PATCH] This commit was manufactured by cvs2svn to create branch 'unlabeled-1.1.2'. --- .cvsignore | 14 - AUTHORS | 11 - COPYING | 504 ----- ChangeLog | 25 - Makefile.am | 27 - NEWS | 34 - README | 138 -- TODO | 60 - bootstrap.sh | 42 - configure.ac | 212 --- example/.cvsignore | 15 - example/.gdb.util | 57 - example/.gdbinit | 23 - example/ChangeLog | 25 - example/HELLO-ja.utf8 | 30 - example/HELLO-ja.xml | 66 - example/HELLO.utf8 | 30 - example/HELLO.xml | 66 - example/MEdit.ja | 153 -- example/Makefile.am | 76 - example/linebreak.c | 123 -- example/mconv.c | 346 ---- example/mdate.c | 215 --- example/mdump.c | 605 ------ example/medit.c | 2700 --------------------------- example/mimx-anthy.c | 330 ---- example/mimx-ispell.c | 202 -- example/mview.c | 384 ---- m17n-config.in | 105 -- src/.cvsignore | 13 - src/ChangeLog | 25 - src/Makefile.am | 89 - src/README | 23 - src/character.c | 517 ------ src/character.h | 283 --- src/charset.c | 1455 --------------- src/charset.h | 253 --- src/chartab.c | 970 ---------- src/chartab.h | 30 - src/coding.c | 4863 ------------------------------------------------- src/coding.h | 31 - src/database.c | 852 --------- src/database.h | 30 - src/draw.c | 2635 --------------------------- src/font-flt.c | 1537 ---------------- src/fontset.h | 37 - src/input-gui.c | 730 -------- src/input.c | 2358 ------------------------ src/input.h | 84 - src/internal.h | 605 ------ src/language.c | 250 --- src/language.h | 26 - src/linkcore.c | 32 - src/linkgui.c | 33 - src/linkshell.c | 32 - src/locale.c | 610 ------- src/m17n-X.c | 2156 ---------------------- src/m17n-X.h | 161 -- src/m17n-core.c | 758 -------- src/m17n-core.h | 529 ------ src/m17n-misc.h | 123 -- src/m17n.c | 122 -- src/m17n.h | 1257 ------------- src/mlocale.h | 30 - src/mtext.c | 2491 ------------------------- src/mtext.h | 68 - src/plist.c | 1173 ------------ src/plist.h | 97 - src/symbol.c | 698 ------- src/symbol.h | 56 - src/textprop.c | 2855 ----------------------------- src/textprop.h | 69 - 72 files changed, 37664 deletions(-) delete mode 100644 .cvsignore delete mode 100644 AUTHORS delete mode 100644 COPYING delete mode 100644 ChangeLog delete mode 100644 Makefile.am delete mode 100644 NEWS delete mode 100644 README delete mode 100644 TODO delete mode 100755 bootstrap.sh delete mode 100644 configure.ac delete mode 100644 example/.cvsignore delete mode 100644 example/.gdb.util delete mode 100644 example/.gdbinit delete mode 100644 example/ChangeLog delete mode 100644 example/HELLO-ja.utf8 delete mode 100644 example/HELLO-ja.xml delete mode 100644 example/HELLO.utf8 delete mode 100644 example/HELLO.xml delete mode 100644 example/MEdit.ja delete mode 100644 example/Makefile.am delete mode 100644 example/linebreak.c delete mode 100644 example/mconv.c delete mode 100644 example/mdate.c delete mode 100644 example/mdump.c delete mode 100644 example/medit.c delete mode 100644 example/mimx-anthy.c delete mode 100644 example/mimx-ispell.c delete mode 100644 example/mview.c delete mode 100644 m17n-config.in delete mode 100644 src/.cvsignore delete mode 100644 src/ChangeLog delete mode 100644 src/Makefile.am delete mode 100644 src/README delete mode 100644 src/character.c delete mode 100644 src/character.h delete mode 100644 src/charset.c delete mode 100644 src/charset.h delete mode 100644 src/chartab.c delete mode 100644 src/chartab.h delete mode 100644 src/coding.c delete mode 100644 src/coding.h delete mode 100644 src/database.c delete mode 100644 src/database.h delete mode 100644 src/draw.c delete mode 100644 src/font-flt.c delete mode 100644 src/fontset.h delete mode 100644 src/input-gui.c delete mode 100644 src/input.c delete mode 100644 src/input.h delete mode 100644 src/internal.h delete mode 100644 src/language.c delete mode 100644 src/language.h delete mode 100644 src/linkcore.c delete mode 100644 src/linkgui.c delete mode 100644 src/linkshell.c delete mode 100644 src/locale.c delete mode 100644 src/m17n-X.c delete mode 100644 src/m17n-X.h delete mode 100644 src/m17n-core.c delete mode 100644 src/m17n-core.h delete mode 100644 src/m17n-misc.h delete mode 100644 src/m17n.c delete mode 100644 src/m17n.h delete mode 100644 src/mlocale.h delete mode 100644 src/mtext.c delete mode 100644 src/mtext.h delete mode 100644 src/plist.c delete mode 100644 src/plist.h delete mode 100644 src/symbol.c delete mode 100644 src/symbol.h delete mode 100644 src/textprop.c delete mode 100644 src/textprop.h diff --git a/.cvsignore b/.cvsignore deleted file mode 100644 index 66ce178..0000000 --- a/.cvsignore +++ /dev/null @@ -1,14 +0,0 @@ -stamp-h* -aclocal.m4 -autoscan.log -configure -configure.scan -*.gz -autom4te.cache -config.* -libtool -m17n-config -Makefile.in -Makefile -.deps -.libs diff --git a/AUTHORS b/AUTHORS deleted file mode 100644 index d0cb331..0000000 --- a/AUTHORS +++ /dev/null @@ -1,11 +0,0 @@ -Kenichi Handa - Core developper. - -Mikiko Nishikimi - Core developper. - -Naoto Takahashi - Core developper. - -Satoru Tomura - Core developper. diff --git a/COPYING b/COPYING deleted file mode 100644 index b1e3f5a..0000000 --- a/COPYING +++ /dev/null @@ -1,504 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff --git a/ChangeLog b/ChangeLog deleted file mode 100644 index ba13825..0000000 --- a/ChangeLog +++ /dev/null @@ -1,25 +0,0 @@ -2004-03-01 Kenichi Handa - - * Version 1.0 released. - - -Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - -This file is part of the m17n library. - -The m17n library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public License -as published by the Free Software Foundation; either version 2.1 of -the License, or (at your option) any later version. - -The m17n library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with the m17n library; if not, write to the Free -Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307, USA. diff --git a/Makefile.am b/Makefile.am deleted file mode 100644 index 449d8e6..0000000 --- a/Makefile.am +++ /dev/null @@ -1,27 +0,0 @@ -# Makefile.am -- top level Makefile for the m17n library. -# Copyright (C) 2003, 2004 -# National Institute of Advanced Industrial Science and Technology (AIST) -# Registration Number H15PRO112 - -# This file is part of the m17n library. - -# The m17n library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public License -# as published by the Free Software Foundation; either version 2.1 of -# the License, or (at your option) any later version. - -# The m17n library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. - -# You should have received a copy of the GNU Lesser General Public -# License along with the m17n library; if not, write to the Free -# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -# 02111-1307, USA. - -## Process this file with Automake to create Makefile.in - -SUBDIRS = src example - -bin_SCRIPTS = m17n-config diff --git a/NEWS b/NEWS deleted file mode 100644 index d907f43..0000000 --- a/NEWS +++ /dev/null @@ -1,34 +0,0 @@ -NEWS -- What's new in the m17n library. -*- outline -*- -Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 -See the end for copying conditions. - - -* Changes in the m17n library 0.9 - -** Released. - - -* Copyright information - -Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - -This file is part of the m17n library. - -The m17n library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public License -as published by the Free Software Foundation; either version 2.1 of -the License, or (at your option) any later version. - -The m17n library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with the m17n library; if not, write to the Free -Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307, USA. diff --git a/README b/README deleted file mode 100644 index b410250..0000000 --- a/README +++ /dev/null @@ -1,138 +0,0 @@ -This directory tree holds version 0.9 of the m17n library. -*- text -*- - -Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 -See the end for copying conditions. - -The m17n library is a multilingual text processing library for the C -language. - -(1) INSTALLATION - -(1-1) From CVS working directory. - -Run the script "bootstrap.sh" in this directory. It is tested that -the script run successfully with these versions of auto tools. - - libtool-1.4 - automake-1.4p5 - autoconf-2.52 - -Then, proceed to the next step. - -(1-2) From the tarball. - -The m17n library utilizes these extra libraries. It is recommened to -install them before running the "configure" script. The script will -find out the existence of them automatically. - - libxml2 -- http://xmlsoft.org/ - fribidi -- http://fribidi.sourceforge.net/ - freetype -- http://www.freetype.org/ - libotf -- http://www.m17n.org/libotf/ - -The sample program medit utilizes this Japanese inputting system. It -is also recommened to install it. - - anthy -- http://anthy.sourceforge.jp/ - -The sample program medit and mdump utilize this Thai word-boundary -finder. It is also recommened to install it. - - wordcut -- http://thaiwordseg.sourceforge.net/ - -Then, type the followings on the command line. - - % ./configure - % make - % make install - -Note that this package assumes an ANSI C compiler such as gcc. It -will not compile with an old-style K&R compiler. - -The default installation path is "/usr/local". -Thus, these header files are installed in /usr/local/include: - m17n.h, m17n-core.h, m17n-gui.h, m17n-err.h, m17n-X.h -These library files are installed in /usr/local/lib: - libm17n.{a,so,la} - libm17n-core.{a,so,la} - libm17n-X.{a,so,la} - libimx-anthy.{a,so,la}, - libimx-ispell.{a,so,la}, -This shell script is installed in /usr/local/bin: - m17n-config -These sample programs are installed in /usr/local/bin too: - mconv, mdate, mview, mdump, medit - -This file under `example' sub-directory is a Japanese resource file -for medit. It is not installed but useful in Japanese locale. Copy -it to your home directory (or, for instance, -/usr/X11R6/lib/X11/ja/app-defaults) and rename it to "MEdit" if you -want to see labels in Japanese: - MEdit.ja - -These text files under `example' sub-directory are not installed but -useful for testing the rendering engine of the m17n library: - HELLO.utf8 HELLO.xml HELLO-ja.utf8 HELLO-ja.xml -XXX.xml are generated from XXX.utf8 by attaching text property -`langauge' and serializing. - -Please read also INSTALL for the generic installation instructions. - - -(2) DATABASE - -The m17n library utilizes the m17n database avairable at: - http://www.m17n.org/m17n-lib/m17n-db -Without this database, the m17n library loses half its value. Please -install it too before you try the above sample programs or develop a -program that uses the m17n library. - - -(3) DOCUMENTATION - -This page has a link to full documentaion of the m17n library: - http://www.m17n.org/m17n-lib - -Actually, the documentation was generated by Doxygen using comments in -the source files. There are English and Japanese comments in -parallel, but plese note that Japanese comments are not updated for -long. - -(4) USAGE - -The library provides three levels of APIs, CORE, SHELL, and GUI. For -CORE API, include , for SHELL API, include , and -for GUI API, include and . See the -documementation above, or the manual of m17nIntro(3) for more detail. - -The shell script "m17n-config" helps compiling and linking of a -program that uses the m17n library. For instance this compiles PROG.c -that uses SHELL API and builds executable PROG. - - % gcc -o PROG `m17n-config --clags` `m17n-config --libs` PROG.c - ----------------------------------------------------------------------- -Copyright information - -Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - -This file is part of the m17n library. - -The m17n library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public License -as published by the Free Software Foundation; either version 2.1 of -the License, or (at your option) any later version. - -The m17n library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with the m17n library; if not, write to the Free -Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307, USA. diff --git a/TODO b/TODO deleted file mode 100644 index 9b07fef..0000000 --- a/TODO +++ /dev/null @@ -1,60 +0,0 @@ -TODO -- todo list for the m17n library. -*- outline -*- -Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 -See the end for copying conditions. - - -* soon - -** Explicitely list up managed objects and describe them. - -** Allow properties to M-text itself, not to a specific region. - - -* later - -** Add in MFont to allow any property. - -** Make such an M-text modifiable that has a format other than -MTEXT_FORMAT_UTF_8. - -** Allow regex for font properties. - -** Should we change the type of property value from (void *) to -MPropValue? - -** Vietnames FLT needs compositions. - -** Lock and unlock M-text. - -** Improve the handling of scratch gstring. - -** Imporve the font selection for characters of the same script. - - -* done - - -* Copyright information - -Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - -This file is part of the m17n library. - -The m17n library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public License -as published by the Free Software Foundation; either version 2.1 of -the License, or (at your option) any later version. - -The m17n library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with the m17n library; if not, write to the Free -Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307, USA. diff --git a/bootstrap.sh b/bootstrap.sh deleted file mode 100755 index 38e046a..0000000 --- a/bootstrap.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/sh -# bootstrap.sh -- shell script to build the m17n library from CVS. -# Copyright (C) 2003, 2004 -# National Institute of Advanced Industrial Science and Technology (AIST) -# Registration Number H15PRO112 -# See the end for copying conditions. - -echo "Running libtoolize..." -libtoolize --automake -echo "Running aclocal..." -aclocal -echo "Running autoheader..." -autoheader -echo "Running automake..." -automake -a -echo "Running autoconf..." -autoconf -echo "The remaining steps to install this library are:" -echo " % ./configure" -echo " % make" -echo " % make install" - -# Copyright (C) 2003, 2004 -# National Institute of Advanced Industrial Science and Technology (AIST) -# Registration Number H15PRO112 - -# This file is part of the m17n library. - -# The m17n library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public License -# as published by the Free Software Foundation; either version 2.1 of -# the License, or (at your option) any later version. - -# The m17n library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. - -# You should have received a copy of the GNU Lesser General Public -# License along with the m17n library; if not, write to the Free -# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -# 02111-1307, USA. diff --git a/configure.ac b/configure.ac deleted file mode 100644 index aa89e21..0000000 --- a/configure.ac +++ /dev/null @@ -1,212 +0,0 @@ -dnl configure.ac -- autoconf script for the m17n library. - -dnl Copyright (C) 2003, 2004 -dnl National Institute of Advanced Industrial Science and Technology (AIST) -dnl Registration Number H15PRO112 - -dnl This file is part of the m17n library. - -dnl The m17n library is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Lesser General Public License -dnl as published by the Free Software Foundation; either version 2.1 of -dnl the License, or (at your option) any later version. - -dnl The m17n library is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl Lesser General Public License for more details. - -dnl You should have received a copy of the GNU Lesser General Public -dnl License along with the m17n library; if not, write to the Free -dnl Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -dnl 02111-1307, USA. - -dnl Process this file with autoconf to produce a configure script. - -AC_INIT(m17n-lib, 1.0, m17n-lib-bug@m17n.org) -AM_INIT_AUTOMAKE(m17n-lib, 1.0) -AM_CONFIG_HEADER(src/config.h) - -# Checks for programs for compiling. -AC_PROG_CC -AC_LIBTOOL_DLOPEN -AC_LIBLTDL_CONVENIENCE -AM_PROG_LIBTOOL - -# Checks for X libraries. -AC_PATH_XTRA - -# Checks for standard header files. -AC_HEADER_STDC -AC_HEADER_DIRENT -AC_HEADER_TIME -AC_CHECK_HEADERS([fcntl.h langinfo.h limits.h locale.h stdlib.h \ - string.h strings.h sys/time.h unistd.h]) - -# Checks for typedefs, structures, and compiler characteristics. -AC_C_CONST -AC_C_INLINE -AC_TYPE_SIZE_T -AC_STRUCT_TM - -# Checks for endian. This influence the default UTF-16 definition. -AC_C_BIGENDIAN - -# Checks for library functions. -AC_FUNC_ALLOCA -AC_FUNC_MALLOC -AC_FUNC_REALLOC -AC_FUNC_MEMCMP -AC_FUNC_STAT -AC_FUNC_STRCOLL -AC_FUNC_STRFTIME -AC_FUNC_STRTOD -AC_CHECK_FUNCS(memmove memset nl_langinfo putenv regcomp setlocale) -AC_CHECK_FUNCS(strchr strdup gettimeofday) - -# Check several libraries without adding -lxxx to LIBS, without -# defining HAVE_LIBXXX nor HAVE_XXX_H. Instead, define XXX_LD_FLAGS -# and HAVE_XXX if library XXX is available. - -# Check for fribidi library. -AC_CHECK_LIB(fribidi, fribidi_set_mirroring, HAVE_FRIBIDI=yes, HAVE_FRIBIDI=no) -AC_CHECK_HEADER(fribidi/fribidi.h,, HAVE_FRIBIDI=no) -if test "x$HAVE_FRIBIDI" = "xyes"; then - AC_DEFINE(HAVE_FRIBIDI, 1, - [Define to 1 if you have Fribidi library and header file.]) - FRIBIDI_LD_FLAGS="-lfribidi"; -fi -AC_SUBST(FRIBIDI_LD_FLAGS) - -# Check for otflib usability. -AC_CHECK_LIB(otf, OTF_open, HAVE_OTF=yes, HAVE_OTF=no) -save_CPPFLAGS=$CPPFLAGS -AC_CHECK_PROG(HAVE_OTFLIB_CONFIG, libotf-config, yes) -if test "x$HAVE_OTFLIB_CONFIG" = "xyes"; then - OTFLIB_INC=`libotf-config --cflags` - CPPFLAGS="$CPPFLAGS $OTFLIB_INC" -fi -AC_CHECK_HEADER(otf.h,, HAVE_OTF=no) -CPPFLAGS=$save_CPPFLAGS -if test "x$HAVE_OTF" = "xyes"; then - AC_DEFINE(HAVE_OTF, 1, - [Define to 1 if you have OTF library and header file.]) - OTF_LD_FLAGS="-lotf"; -fi -AC_SUBST(OTF_LD_FLAGS) - -# Check for Freetype2 usability. -AC_CHECK_PROG(HAVE_FREETYPE_CONFIG, freetype-config, yes) -if test "x$HAVE_FREETYPE_CONFIG" = "xyes"; then - FREETYPE_INC=`freetype-config --cflags` - save_CPPFLAGS=$CPPFLAGS - CPPFLAGS="$CPPFLAGS $FREETYPE_INC" - AC_CHECK_HEADER(ft2build.h, HAVE_FREETYPE=yes, - HAVE_FREETYPE=no CPPFLAGS=$save_CPPFLAGS) - if test "x$HAVE_FREETYPE" = "xyes" ; then - FREETYPE_LD_FLAGS=`freetype-config --libs`; - save_LIBS=$LIBS - LIBS="$LIBS $FREETYPE_LD_FLAGS" - AC_CHECK_LIB(freetype, FT_Init_FreeType, HAVE_FREETYPE=yes, - HAVE_FREETYPE=no) - LIBS=$save_LIBS - if test "x$HAVE_FREETYPE" = "xyes"; then - AC_DEFINE(HAVE_FREETYPE, 1, - [Define to 1 if you have FreeType library and header file.]) - fi - fi -fi -AC_SUBST(FREETYPE_LD_FLAGS) - -# Check for libxml2 usability. -AC_CHECK_LIB(xml2, xmlParseMemory, HAVE_XML2=yes, HAVE_XML2=no) -if test "x$HAVE_XML2" = "xyes"; then - save_CPPFLAGS=$CPPFLAGS - CPPFLAGS="$CPPFLAGS -I/usr/include/libxml2" - AC_CHECK_HEADER(libxml/tree.h,, HAVE_XML2=no, /**/) - if test "x$HAVE_XML2" = "xyes"; then - AC_DEFINE(HAVE_XML2, 1, - [Define to 1 if you have libxml2 library and header file]) - XML2_LD_FLAGS="-lxml2" - else - CPPFLAGS=$save_CPPFLAGS - fi -fi -AC_SUBST(XML2_LD_FLAGS) - -# Check for Anthy usability. -AC_CHECK_LIB(anthydic, anthy_init_sessions, HAVE_ANTHY=yes, HAVE_ANTHY=no) -if test "x$HAVE_ANTHY" = "xyes"; then - AC_CHECK_LIB(anthy, anthy_init, HAVE_ANTHY=yes, HAVE_ANTHY=no, -lanthydic) - if test "x$HAVE_ANTHY" = "xyes"; then - AC_CHECK_HEADER(anthy/anthy.h, HAVE_ANTHY=yes, HAVE_ANTHY=no) - if test "x$HAVE_ANTHY" = "xyes"; then - AC_DEFINE(HAVE_ANTHY, 1, - [Define to 1 if you have Anthy library and header file]) - ANTHY_LD_FLAGS="-lanthy -lanthydic" - fi - fi -fi -AC_SUBST(ANTHY_LD_FLAGS) - -# Check for Ispell usability. -AC_CHECK_PROG(HAVE_ISPELL, ispell, yes) -if test "x$HAVE_ISPELL" = "xyes"; then - AC_DEFINE(HAVE_ISPELL, 1, [Define if ispell is available.]) -fi - -# Check for libwordcut (for Thai). -AC_CHECK_LIB(wordcut, wordcut_init, HAVE_WORDCUT=yes, HAVE_WORDCUT=no) -if test "x$HAVE_WORDCUT" = "xyes"; then - if test -f "/usr/share/wordcut/tdict.wcd"; then - tdict="/usr/share/wordcut/tdict.wcd" - elif test -f "/usr/local/share/wordcut/tdict.wcd"; then - tdict="/usr/local/share/wordcut/tdict.wcd" - fi - echo "TDICT=$tdict" - if test "x$tdict" != "x"; then - AC_DEFINE(HAVE_WORDCUT, 1, - [Define if you have the wordcut library and header file]) - AC_DEFINE_UNQUOTED(WORDCUT_TDICT, "$tdict", [Define to tdict file name]) - WORDCUT_LD_FLAGS=-lwordcut - fi -fi -AC_SUBST(WORDCUT_LD_FLAGS) - -AC_ARG_ENABLE(xom, - [ --enable-xom build and install XOM library.], - XOM="$enableval") - -AC_ARG_WITH(efence, - [ --with-efence build example programs with efence.], - EFENCE="$withval") -AC_CHECK_LIB(efence, malloc, HAVE_EFENCE=yes) - -if test "x$EFENCE" = "xyes" && test "x$HAVE_EFENCE" = "xyes"; then - EFENCE_LIB=-lefence -fi -AC_SUBST(EFENCE_LIB) - -case $host_os in -darwin* | rhapsody*) - AC_DEFINE(DLOPEN_SHLIB_EXT, ".dylib", - [Define to loadable module extention]);; -esac - -AC_CONFIG_FILES([Makefile - src/Makefile - example/Makefile - m17n-config - ]) - -if test "x$XOM" = "xyes"; then - AC_CONFIG_FILES(omM17N/Makefile) -fi - -AC_OUTPUT - -dnl Local Variables: -dnl comment-start: "dnl " -dnl comment-end: "" -dnl comment-start-skip: "\\bdnl\\b\\s *" -dnl End: diff --git a/example/.cvsignore b/example/.cvsignore deleted file mode 100644 index 4737409..0000000 --- a/example/.cvsignore +++ /dev/null @@ -1,15 +0,0 @@ -*.lo -*.la -mconv -mdate -mdump -medit -mview -a.out -stamp-h* -config.h -config.h.in -Makefile.in -Makefile -.deps -.libs diff --git a/example/.gdb.util b/example/.gdb.util deleted file mode 100644 index 9fafb7c..0000000 --- a/example/.gdb.util +++ /dev/null @@ -1,57 +0,0 @@ -define xchartab -set mdebug_dump_chartab ($, 0) -echo \n -end - -define xsymbol -set mdebug_dump_symbol ($, 0) -echo \n -end - -define xmtext -set mdebug_dump_mtext ($, 1, 0) -echo \n -end - -define xplist -set mdebug_dump_plist ($, 0) -echo \n -end - -define xinterval -set dump_interval ($arg0, 0) -echo \n -end - -define xfont -set mdebug_dump_font ($) -echo \n -end - -define xfontset -set mdebug_dump_fontset ($, 0) -echo \n -end - -define xface -set mdebug_dump_face ($, 0) -echo \n -end - -define xgstring -set dump_gstring (gstring, 0) -echo \n -end - -define xim -set mdebug_dump_im ($, 0) -echo \n -end - -define xflush -call XFlush (display) -end - -define xsynch -call XSynchronize (display, 1) -end diff --git a/example/.gdbinit b/example/.gdbinit deleted file mode 100644 index db736ae..0000000 --- a/example/.gdbinit +++ /dev/null @@ -1,23 +0,0 @@ -set main - -# br mdebug_hook - -source .gdb.util - -set env LD_LIBRARY_PATH=../src/.libs:./.libs:/usr/local/lib - -set env EF_ALLOW_MALLOC_0=1 -set env EF_PROTECT_FREE=1 -set env EF_OVERRUN_DETECTION=1 -set env EF_FREE_WIPES=1 - -set env MDEBUG_INIT=1 -set env MDEBUG_FINI=1 -set env MDEBUG_CHARSET=1 -set env MDEBUG_CODING=1 -set env MDEBUG_DATABASE=1 -set env MDEBUG_FONT=1 -set env MDEBUG_FONT_FLT=0 -set env MDEBUG_FONT_OTF=1 - -set env PURIFYOPTIONS=-chain-length="20" diff --git a/example/ChangeLog b/example/ChangeLog deleted file mode 100644 index ba13825..0000000 --- a/example/ChangeLog +++ /dev/null @@ -1,25 +0,0 @@ -2004-03-01 Kenichi Handa - - * Version 1.0 released. - - -Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - -This file is part of the m17n library. - -The m17n library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public License -as published by the Free Software Foundation; either version 2.1 of -the License, or (at your option) any later version. - -The m17n library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with the m17n library; if not, write to the Free -Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307, USA. diff --git a/example/HELLO-ja.utf8 b/example/HELLO-ja.utf8 deleted file mode 100644 index 102fcbc..0000000 --- a/example/HELLO-ja.utf8 +++ /dev/null @@ -1,30 +0,0 @@ -ヨーロッパ - 英語 (English) Hello - フランス語 (français) Bonjour, Salut - ドイツ語 (Deutsch) Guten Tag, Grüß Gott - スロバキア語 (slovensky) Dobrý deň - ロシア語 (русский) Здравствуйте! - ギリシャ語 (ελληνικά) Γειάσας - -中近東・アフリカ - トルコ語 (Türkçe) Merhaba - グルジア語 (ქართული) გამარჯობათ! - アラビア語 (اَلْعَرَبِيَّةُ)‎ اَلسَّلَامُ عَلَيْكُم - ペルシャ語 (فارسی)‎ سلام عليکم - ヘブライ語 (עִבְרִית)‎ שָׁלוֹם - アムハラ語 (አማርኛ) ሠላም - -南・東南アジア - ヒンディー語 (हिंदी) नमस्ते, नमस्कार । - マラヤラム語(മലയാളം) നമസ്കാരം - タミール語 (தமிழ்) வணக்கம் - チベット語 (བོད་སྐད་) བཀྲ་ཤིས་བདེ་ལེགས༎ (ex: བསྒྲུབས, ཧཱུཾ) - クメール語 (ខ្មៃរ) ជំរាបសួរ (ex: ក្ក្រឿ៌) - ベトナム語 (Tiếng Việt) Chào bạn - タイ語 (ภาษาไทย) สวัสดีครับ, สวัสดีค่ะ - ラオ語 (ພາສາລາວ) ສະບາຍດີ, ຂໍໃຫ້ໂຊກດີ - -東アジア - 日本語 こんにちは - 中国語 (汉语,普通话) 你好 - 韓国語 (한글) 안녕하세요 diff --git a/example/HELLO-ja.xml b/example/HELLO-ja.xml deleted file mode 100644 index 9a1eeaf..0000000 --- a/example/HELLO-ja.xml +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - -]> - - - - - - - - - - - - - - - - - - - - - - - - -ヨーロッパ - 英語 (English) Hello - フランス語 (français) Bonjour, Salut - ドイツ語 (Deutsch) Guten Tag, Grüß Gott - スロバキア語 (slovensky) Dobrý deň - ロシア語 (русский) Здравствуйте! - ギリシャ語 (ελληνικά) Γειάσας - -中近東・アフリカ - トルコ語 (Türkçe) Merhaba - グルジア語 (ქართული) გამარჯობათ! - アラビア語 (اَلْعَرَبِيَّةُ)‎ اَلسَّلَامُ عَلَيْكُم - ペルシャ語 (فارسی)‎ سلام عليکم - ヘブライ語 (עִבְרִית)‎ שָׁלוֹם - アムハラ語 (አማርኛ) ሠላም - -南・東南アジア - ヒンディー語 (हिंदी) नमस्ते, नमस्कार । - マラヤラム語(മലയാളം) നമസ്കാരം - タミール語 (தமிழ்) வணக்கம் - チベット語 (བོད་སྐད་) བཀྲ་ཤིས་བདེ་ལེགས༎ (ex: བསྒྲུབས, ཧཱུཾ) - クメール語 (ខ្មៃរ) ជំរាបសួរ (ex: ក្ក្រឿ៌) - ベトナム語 (Tiếng Việt) Chào bạn - タイ語 (ภาษาไทย) สวัสดีครับ, สวัสดีค่ะ - ラオ語 (ພາສາລາວ) ສະບາຍດີ, ຂໍໃຫ້ໂຊກດີ - -東アジア - 日本語 こんにちは - 中国語 (汉语,普通话) 你好 - 韓国語 (한글) 안녕하세요 - diff --git a/example/HELLO.utf8 b/example/HELLO.utf8 deleted file mode 100644 index dac8287..0000000 --- a/example/HELLO.utf8 +++ /dev/null @@ -1,30 +0,0 @@ -Europe - English Hello - French (français) Bonjour, Salut - German (Deutsch) Guten Tag, Grüß Gott - Slovak (slovensky) Dobrý deň - Russian (русский) Здравствуйте! - Greek (ελληνικά) Γειάσας - -Middle Near East/Africa - Turkish (Türkçe) Merhaba - Georgian (ქართული) გამარჯობათ! - Arabic (اَلْعَرَبِيَّةُ)‎ اَلسَّلَامُ عَلَيْكُم - Persian (فارسی)‎ سلام عليکم - Hebrew (עִבְרִית)‎ שָׁלוֹם - Amharic (አማርኛ) ሠላም - -South/South-East Asia - Hindi (हिंदी) नमस्ते, नमस्कार । - Malayalam (മലയാളം) നമസ്കാരം (ex: à´¨+്+à´°=ന്ര) - Tamil (தமிழ்) வணக்கம் - Tibetan (བོད་སྐད་) བཀྲ་ཤིས་བདེ་ལེགས༎ (ex: བསྒྲུབས, ཧཱུཾ) - Khmer (ខ្មៃរ) ជំរាបសួរ (ex: ក្ក្រឿ៌) - Vietnamese (Tiếng Việt) Chào bạn - Thai (ภาษาไทย) สวัสดีครับ, สวัสดีค่ะ - Lao (ພາສາລາວ) ສະບາຍດີ, ຂໍໃຫ້ໂຊກດີ - -East Asia - Japanese (日本語) こんにちは - Chinese (汉语,普通话) 你好 - Korean (한글) 안녕하세요 diff --git a/example/HELLO.xml b/example/HELLO.xml deleted file mode 100644 index dca1e76..0000000 --- a/example/HELLO.xml +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - -]> - - - - - - - - - - - - - - - - - - - - - - - - -Europe - English Hello - French (français) Bonjour, Salut - German (Deutsch) Guten Tag, Grüß Gott - Slovak (slovensky) Dobrý deň - Russian (русский) Здравствуйте! - Greek (ελληνικά) Γειάσας - -Middle Near East/Africa - Turkish (Türkçe) Merhaba - Georgian (ქართული) გამარჯობათ! - Arabic (اَلْعَرَبِيَّةُ)‎ اَلسَّلَامُ عَلَيْكُم - Persian (فارسی)‎ سلام عليکم - Hebrew (עִבְרִית)‎ שָׁלוֹם - Amharic (አማርኛ) ሠላም - -South/South-East Asia - Hindi (हिंदी) नमस्ते, नमस्कार । - Malayalam (മലയാളം) നമസ്കാരം (ex: à´¨+്+à´°=ന്ര) - Tamil (தமிழ்) வணக்கம் - Tibetan (བོད་སྐད་) བཀྲ་ཤིས་བདེ་ལེགས༎ (ex: བསྒྲུབས, ཧཱུཾ) - Khmer (ខ្មៃរ) ជំរាបសួរ (ex: ក្ក្រឿ៌) - Vietnamese (Tiếng Việt) Chào bạn - Thai (ภาษาไทย) สวัสดีครับ, สวัสดีค่ะ - Lao (ພາສາລາວ) ສະບາຍດີ, ຂໍໃຫ້ໂຊກດີ - -East Asia - Japanese (日本語) こんにちは - Chinese (汉语,普通话) 你好 - Korean (한글) 안녕하세요 - diff --git a/example/MEdit.ja b/example/MEdit.ja deleted file mode 100644 index 5c8e6cf..0000000 --- a/example/MEdit.ja +++ /dev/null @@ -1,153 +0,0 @@ -! -*- coding: euc-jp; -*- -*.fontSet: -etl-fixed-medium-r-normal--24-*-*-*-*,-*-*-medium-r-normal--24-*-*-*-* -*.international: True -*.File.label: ¥Õ¥¡¥¤¥ë -*.Cursor.label: ¥«¡¼¥½¥ë -*.Bidi.label: ½ñ»úÊý¸þ -*.LineBreak.label: ¹Ôʬ³ä -*.InputMethod.label: ÆþÎϥ᥽¥Ã¥É -*.Face.label: ¥Õ¥§¡¼¥¹ -*.Lang.label: ¸À¸ì -*.Size.label: ¥µ¥¤¥º -*.Family.label: ¥Õ¥¡¥ß¥ê¡¼ -*.Style.label: ¥¹¥¿¥¤¥ë -*.Color.label: ¿§ -*.Misc.label: ¤½¤Î¾ -*.Pop Face.label: ¥Ý¥Ã¥× -*Abkhazian.label:¥¢¥Ö¥Ï¥º¸ì -*Afar.label:¥¢¥Õ¥¡¥ë¸ì -*Afrikaans.label:¥¢¥Õ¥ê¥«¡¼¥ó¥¹¸ì -*Albanian.label:¥¢¥ë¥Ð¥Ë¥¢¸ì -*Amharic.label:¥¢¥à¥Ï¥é¸ì -*Arabic.label:¥¢¥é¥Ó¥¢¸ì -*Armenian.label:¥¢¥ë¥á¥Ë¥¢¸ì -*Assamese.label:¥¢¥Ã¥µ¥à¸ì -*Aymara.label:¥¢¥¤¥Þ¥é¸ì -*Azerbaijani.label:¥¢¥¼¥ë¥Ð¥¤¥¸¥ã¥ó¸ì -*Bashkir.label:¥Ð¥·¥å¥­¡¼¥ë¸ì -*Basque.label:¥Ð¥¹¥¯¸ì -*Bengali.label:¥Ù¥ó¥¬¥ë¸ì -*Bhutani.label:¥Ö¡¼¥¿¥ó¸ì -*Bihari.label:¥Ó¥Ï¡¼¥ë¸ì -*Bislama.label:¥Ó¥¹¥é¥Þ¸ì -*Breton.label:¥Ö¥ë¥È¥ó¸ì -*Bulgarian.label:¥Ö¥ë¥¬¥ê¥¢¸ì -*Burmese.label:¥Ó¥ë¥Þ¸ì -*Byelorussian.label:Çò¥í¥·¥¢¸ì -*Cambodian.label:¥«¥ó¥Ü¥¸¥¢¸ì -*Catalan.label:¥«¥¿¥í¥Ë¥¢¸ì -*Chinese.label:Ãæ¹ñ¸ì -*Corsican.label:¥³¥ë¥·¥«¸ì -*Croatian.label:¥¯¥í¥¢¥Á¥¢¸ì -*Czech.label:¥Á¥§¥³¸ì -*Danish.label:¥Ç¥ó¥Þ¡¼¥¯¸ì -*Dutch.label:¥ª¥é¥ó¥À¸ì -*English.label:±Ñ¸ì -*Esperanto.label:¥¨¥¹¥Ú¥é¥ó¥È -*Estonian.label:¥¨¥¹¥È¥Ë¥¢¸ì -*Faeroese.label:¥Õ¥§¡¼¥í¡¼¸ì -*Farsi.label:¥Ú¥ë¥·¥¢¸ì -*Fiji.label:¥Õ¥£¥¸¡¼¸ì -*Finnish.label:¥Õ¥£¥ó¥é¥ó¥É¸ì -*French.label:¥Õ¥é¥ó¥¹¸ì -*Frisian.label:¥Õ¥ê¥¸¥¢¸ì -*Galician.label:¥¬¥ê¥·¥¢¸ì -*Gaelic(Scottish).label:¥²¡¼¥ë¸ì¡Ê¥¹¥³¥Ã¥È¥é¥ó¥É¡Ë -*Gaelic(Manx).label:¥²¡¼¥ë¸ì¡Ê¥Þ¥óÅç¡Ë -*Georgian.label:¥°¥ë¥¸¥¢¸ì -*German.label:¥É¥¤¥Ä¸ì -*Greek.label:¥®¥ê¥·¥¢¸ì -*Greenlandic.label:¥°¥ê¡¼¥ó¥é¥ó¥É¸ì -*Guarani.label:¥ï¥é¥Ë¡¼¸ì -*Gujarati.label:¥°¥¸¥ã¥é¡¼¥È¸ì -*Hausa.label:¥Ï¥¦¥µ¸ì -*Hebrew.label:¥Ø¥Ö¥é¥¤¸ì -*Hindi.label:¥Ò¥ó¥Ç¥£¡¼¸ì -*Hungarian.label:¥Ï¥ó¥¬¥ê¡¼¸ì -*Icelandic.label:¥¢¥¤¥¹¥é¥ó¥É¸ì -*Indonesian.label:¥¤¥ó¥É¥Í¥·¥¢¸ì -*Inuktitut.label:¥¤¥Ì¥¯¥Æ¥£¥È¥Ã¥È¸ì -*Inupiak.label:¥¤¥Ì¥Ô¥¢¥Ã¥¯¸ì -*Irish.label:¥¢¥¤¥ë¥é¥ó¥É¸ì -*Italian.label:¥¤¥¿¥ê¥¢¸ì -*Japanese.label:ÆüËܸì -*Javanese.label:¥¸¥ã¥ï¸ì -*Kannada.label:¥«¥ó¥Ê¥À¸ì -*Kashmiri.label:¥«¥·¥å¥ß¡¼¥ë¸ì -*Kazakh.label:¥«¥¶¥Õ¸ì -*Kinyarwanda.label:¥ë¥ï¥ó¥À¸ì -*Kirghiz.label:¥­¥ë¥®¥¹¸ì -*Kirundi.label:¥ë¥ó¥Ç¥£¸ì -*Korean.label:Ä«Á¯¸ì -*Kurdish.label:¥¯¥ë¥É¸ì -*Laothian.label:¥é¥ª¸ì -*Latin.label:¥é¥Æ¥ó¸ì -*Latvian.label:¥é¥È¥ô¥£¥¢¸ì -*Lingala.label:¥ê¥ó¥¬¥é¸ì -*Lithuanian.label:¥ê¥È¥¢¥Ë¥¢¸ì -*Macedonian.label:¥Þ¥±¥É¥Ë¥¢¸ì -*Malagasy.label:¥Þ¥é¥¬¥·¸ì -*Malay.label:¥à¥é¥æ¸ì -*Malayalam.label:¥Þ¥é¥ä¡¼¥é¥à¸ì -*Maltese.label:¥Þ¥ë¥¿¸ì -*Maori.label:¥Þ¥ª¥ê¸ì -*Marathi.label:¥Þ¥é¡¼¥Æ¥£¡¼¸ì -*Moldavian.label:¥â¥ë¥À¥Ó¥¢¸ì -*Mongolian.label:¥â¥ó¥´¥ë¸ì -*Nauru.label:¥Ê¥¦¥ë¸ì -*Nepali.label:¥Í¥Ñ¡¼¥ë¸ì -*Norwegian.label:¥Î¥ë¥¦¥§¡¼¸ì -*Occitan.label:¥×¥í¥ô¥¡¥ó¥¹¸ì -*Oriya.label:¥ª¥ê¥ä¡¼¸ì -*Oromo.label:¥¬¥Ã¥é¸ì -*Pashto.label:¥Ñ¥·¥å¥È¡¼¸ì -*Polish.label:¥Ý¡¼¥é¥ó¥É¸ì -*Portuguese.label:¥Ý¥ë¥È¥¬¥ë¸ì -*Punjabi.label:¥Ñ¥ó¥¸¥ã¡¼¥Ö¸ì -*Quechua.label:¥±¥Á¥å¥¢¸ì -*Rhaeto-Romance.label:¥ì¥È¡¦¥í¥Þ¥ó¥¹¸ì -*Romanian.label:¥ë¡¼¥Þ¥Ë¥¢¸ì -*Russian.label:¥í¥·¥¢¸ì -*Samoan.label:¥µ¥â¥¢¸ì -*Sangro.label:¥µ¥ó¥´¸ì -*Sanskrit.label:¥µ¥ó¥¹¥¯¥ê¥Ã¥È -*Serbian.label:¥»¥ë¥Ó¥¢¸ì -*Serbo-Croatian.label:¥»¥ë¥Ó¥¢¡¦¥¯¥í¥¢¥Á¥¢¸ì -*Sesotho.label:¥½¥È¸ì -*Setswana.label:¥Ä¥ï¥Ê¸ì -*Shona.label:¥·¥ç¥Ê¸ì -*Sindhi.label:¥·¥ó¥É¸ì -*Sinhalese.label:¥·¥ó¥Ï¥é¸ì -*Siswati.label:¥¹¥ï¥Æ¥£¸ì -*Slovak.label:¥¹¥í¥Ð¥­¥¢¸ì -*Slovenian.label:¥¹¥í¥Ù¥Ë¥¢¸ì -*Somali.label:¥½¥Þ¥ê¸ì -*Spanish.label:¥¹¥Ú¥¤¥ó¸ì -*Sundanese.label:¥¹¥ó¥À¸ì -*Swahili.label:¥¹¥ï¥Ò¥ê¸ì -*Swedish.label:¥¹¥¦¥§¡¼¥Ç¥ó¸ì -*Tagalog.label:¥¿¥¬¥í¥°¸ì -*Tajik.label:¥¿¥¸¥¯¸ì -*Tamil.label:¥¿¥ß¡¼¥ë¸ì -*Tatar.label:¥¿¥¿¡¼¥ë¸ì -*Telugu.label:¥Æ¥ë¥°¸ì -*Thai.label:¥¿¥¤¸ì -*Tibetan.label:¥Á¥Ù¥Ã¥È¸ì -*Tigrinya.label:¥Æ¥£¥°¥ê¥Ë¥¢¸ì -*Tonga.label:¥È¥ó¥¬¸ì -*Tsonga.label:¥Ä¥©¥ó¥¬¸ì -*Turkish.label:¥È¥ë¥³¸ì -*Turkmen.label:¥È¥ë¥¯¥á¥ó¸ì -*Twi.label:¥Á¥å¥¤¸ì -*Uighur.label:¥¦¥¤¥°¥ë¸ì -*Ukrainian.label:¥¦¥¯¥é¥¤¥Ê¸ì -*Urdu.label:¥¦¥ë¥É¥¥¡¼¸ì -*Uzbek.label:¥¦¥º¥Ù¥¯¸ì -*Vietnamese.label:¥Ù¥È¥Ê¥à¸ì -*Volapuk.label:¥ô¥©¥é¥Ô¥å¥¯ -*Welsh.label:¥¦¥§¡¼¥ë¥º¸ì -*Wolof.label:¥¦¥©¥í¥Õ¸ì -*Xhosa.label:¥³¥µ¸ì -*Yiddish.label:¥¤¥Ç¥£¥Ã¥·¥å¸ì -*Yoruba.label:¥è¥ë¥Ð¸ì -*Zulu.label:¥º¡¼¥ë¡¼¸ì diff --git a/example/Makefile.am b/example/Makefile.am deleted file mode 100644 index 94c5629..0000000 --- a/example/Makefile.am +++ /dev/null @@ -1,76 +0,0 @@ -# Makefile.am -- example level Makefile for the m17n library. -# Copyright (C) 2003, 2004 -# National Institute of Advanced Industrial Science and Technology (AIST) -# Registration Number H15PRO112 - -# This file is part of the m17n library. - -# The m17n library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public License -# as published by the Free Software Foundation; either version 2.1 of -# the License, or (at your option) any later version. - -# The m17n library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. - -# You should have received a copy of the GNU Lesser General Public -# License along with the m17n library; if not, write to the Free -# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -# 02111-1307, USA. - -## Process this file with Automake to create Makefile.in - -bin_PROGRAMS = mconv mview mdate mdump medit - -common_ldflags = ${top_srcdir}/src/libm17n-core.la ${top_srcdir}/src/libm17n.la -common_ldflags_X = ${top_srcdir}/src/libm17n-X.la - -mdate_SOURCES = mdate.c -mdate_LDADD = ${common_ldflags} - -mconv_SOURCES = mconv.c -mconv_LDADD = ${common_ldflags} - -medit_SOURCES = medit.c linebreak.c -medit_LDADD = ${common_ldflags_X} -medit_LDFLAGS = -lXaw -lXmu @WORDCUT_LD_FLAGS@ - -mview_SOURCES = mview.c -mview_LDADD = ${common_ldflags_X} -mview_LDFLAGS = -lXaw -lXmu - -mdump_SOURCES = mdump.c linebreak.c -mdump_LDADD = ${common_ldflags_X} @WORDCUT_LD_FLAGS@ - -# Input method data files. - -pkgdatadir=$(datadir)/m17n - -EXTRA_DIST = \ - .gdbinit .gdb.util \ - HELLO.utf8 HELLO.xml HELLO-ja.utf8 HELLO-ja.xml MEdit.ja - -# External modules used by the above input methods. - -lib_LTLIBRARIES = libmimx-ispell.la libmimx-anthy.la - -libmimx_ispell_la_SOURCES = mimx-ispell.c -libmimx_ispell_la_LIBADD = ${common_ldflags_X} - -libmimx_anthy_la_SOURCES = mimx-anthy.c -libmimx_anthy_la_LIBADD = ${common_ldflags} -libmimx_anthy_la_LDFLAGS = @ANTHY_LD_FLAGS@ - -# Special targets to test the m17n library with Purify. They are for -# the maintainers only. - -PURIFY=/usr/local/rational/releases/purify.sol.2002.05.00/purify - -purify_medit: medit ../src/.libs/libm17n-core.so ../src/.libs/libm17n.so ../src/.libs/libm17n-X.so linebreak.c - ${PURIFY} gcc -g medit.o linebreak.o -lXaw -lXmu -L/usr/X11R6/lib -R/usr/X11R6/lib -lSM -lICE -lX11 -lXt -L../src/.libs -lm17n-core -lm17n -lm17n-X -ldl - -purify_mdate: mdate.o ../src/.libs/libm17n.so ../src/.libs/libm17n-X.so - ${PURIFY} gcc -g mdate.o -lXaw -lXmu -L/usr/X11R6/lib -R/usr/X11R6/lib -lSM -lICE -lX11 -lXt -L../src/.libs -lm17n -lm17n-X -ldl - diff --git a/example/linebreak.c b/example/linebreak.c deleted file mode 100644 index e5d3efa..0000000 --- a/example/linebreak.c +++ /dev/null @@ -1,123 +0,0 @@ -#include - -#include - -#ifdef HAVE_WORDCUT - -#define THAI_BEG 0x0E00 -#define THAI_END 0x0E6F - -static int wordcut_initiazlied = 0; - -#include -#include -#include - -static Wordcut wordcut; - -static MSymbol Mwordcut_wordbeg, Miso_8859_11; - -static void -init_th_wordcut () -{ - Mwordcut_wordbeg = msymbol (" wordcut-wordseg"); - Miso_8859_11 = msymbol ("iso-8859-11"); -} - -int -thai_line_break (MText *mt, int pos, int from, int to) -{ - WordcutResult result; - MTextProperty *prop; - int pos1, pos2, c, i; - unsigned char *str; - - if (wordcut_initiazlied < 0) - return pos; - if (! wordcut_initiazlied) - { - if (wordcut_init (&wordcut, WORDCUT_TDICT) != 0) - { - wordcut_initiazlied = -1; - return pos; - } - init_th_wordcut (); - wordcut_initiazlied = 1; - } - prop = mtext_get_property (mt, pos, Mwordcut_wordbeg); - if (prop) - { - pos1 = mtext_property_start (prop); - if (pos1 == from) - pos1 = pos; - return pos1; - } - str = alloca (to - from); - pos1 = pos - 1; - while (pos1 >= from - && (c = mtext_ref_char (mt, pos1)) >= THAI_BEG && c <= THAI_END) - str[pos1-- - from] = mchar_encode (Miso_8859_11, c); - pos1++; - pos2 = pos; - while (pos2 < to - && (c = mtext_ref_char (mt, pos2)) >= 0x0E00 && c <= 0x0E6F) - str[pos2++ - from] = mchar_encode (Miso_8859_11, c); - str[pos2 - from] = 0; - wordcut_cut (&wordcut, (char *) (str + pos1 - from), &result); - for (i = 0; i < result.count; i++) - { - int start = pos1 + result.start[i]; - - prop = mtext_property (Mwordcut_wordbeg, Mt, - MTEXTPROP_VOLATILE_WEAK | MTEXTPROP_NO_MERGE); - mtext_attach_property (mt, start, start + result.offset[i], prop); - m17n_object_unref (prop); - } - prop = mtext_get_property (mt, pos, Mwordcut_wordbeg); - pos1 = mtext_property_start (prop); - if (pos1 == from) - pos1 = pos; - return pos1; -} - -#define CHECK_THAI_LINE_BREAK(c, mt, pos, from, to) \ - do { \ - if ((c) >= THAI_BEG && (c) <= THAI_END) \ - return thai_line_break ((mt), (pos), (from), (to)); \ - } while (0) - -#else /* not HAVE_WORDCUT */ - -#define CHECK_THAI_LINE_BREAK(c, mt, pos, from, to) (void) 0 - -#endif /* not HAVE_WORDCUT */ - -int -line_break (MText *mt, int pos, int from, int to, int line, int y) -{ - int c = mtext_ref_char (mt, pos); - int orig_pos = pos; - - if (c == ' ' || c == '\t' || c == '\n') - { - for (pos++; pos < to; pos++) - if ((c = mtext_ref_char (mt, pos)) != ' ' && c != '\t' && c != '\n') - break; - } - else - { - while (pos > from) - { - if (c == ' ' || c == '\t') - break; - CHECK_THAI_LINE_BREAK (c, mt, pos, from, to); - pos--; - c = mtext_ref_char (mt, pos); - } - if (pos == from) - pos = orig_pos; - else - pos++; - } - return pos; -} diff --git a/example/mconv.c b/example/mconv.c deleted file mode 100644 index 7dca6c4..0000000 --- a/example/mconv.c +++ /dev/null @@ -1,346 +0,0 @@ -/* mconv.c -- Code converter. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -/***en - @page mconv convert file code - - @section mconv-synopsis SYNOPSIS - - mconv [ OPTION ... ] [ INFILE [ OUTFILE ] ] - - @section mconv-description DESCRIPTION - - Convert encoding of given files from one to another. - - If INFILE is omitted, the input is taken from standard input. If - OUTFILE is omitted, the output written to standard output. - - The following OPTIONs are available. - -
    - -
  • -f FROMCODE - - FROMCODE is the encoding of INFILE (defaults to UTF-8). - -
  • -t TOCODE - - TOCODE is the encoding of OUTFILE (defaults to UTF-8). - -
  • -k - - Do not stop conversion on error. - -
  • -s - - Suppress warnings. - -
  • -v - - Print progress information. - -
  • -l - - List available encodings. - -
  • --version - - Print version number. - -
  • -h, --help - - Print this message. - -
-*/ - -#ifndef FOR_DOXYGEN - -#include -#include -#include - -#include -#include - -#define VERSION "1.0" - -/* Print all coding system names. */ - -void -list_coding () -{ - MSymbol *codings; - int i, n; - char *name; - int len, clm; - - n = mconv_list_codings (&codings); - clm = 0; - for (i = 0; i < n; i++) - { - name = msymbol_name (codings[i]); - len = strlen (name) + 1; - if (clm + len >= 80) - { - printf ("\n"); - clm = 0; - } - printf (" %s", name); - clm += len; - } - printf ("\n"); - free (codings); -} - - -/* Print the usage of this program (the name is PROG), and exit with - EXIT_CODE. */ - -void -help_exit (char *prog, int exit_code) -{ - char *p = prog; - - while (*p) - if (*p++ == '/') - prog = p; - - printf ("Usage: %s [ OPTION ... ] [ INFILE [ OUTFILE ] ]\n", prog); - printf ("Convert encoding of given files from one to another.\n"); - printf (" If INFILE is omitted, the input is taken from standard input.\n"); - printf (" If OUTFILE is omitted, the output is written to standard output.\n"); - printf ("The following OPTIONs are available.\n"); - printf (" %-13s %s", "-f FROMCODE", - "FROMCODE is the encoding of INFILE (defaults to UTF-8).\n"); - printf (" %-13s %s", "-t TOCODE", - "TOCODE is the encoding of OUTFILE (defaults to UTF-8).\n"); - printf (" %-13s %s", "-k", "Do not stop conversion on error.\n"); - printf (" %-13s %s", "-s", "Suppress warnings.\n"); - printf (" %-13s %s", "-v", "Print progress information.\n"); - printf (" %-13s %s", "-l", "List available encodings.\n"); - printf (" %-13s %s", "--version", "Print version number.\n"); - printf (" %-13s %s", "-h, --help", "Print this message.\n"); - exit (exit_code); -} - - -/* Check invalid bytes found in the last decoding. Text property - Mcharset of such a byte is Mcharset_binary. */ - -void -check_invalid_bytes (MText *mt) -{ - int from = 0, to = 0; - int len = mtext_len (mt); - int first = 1; - - while (to < len) - { - int n = mtext_prop_range (mt, Mcharset, from, NULL, &to, 1); - MSymbol charset - = n > 0 ? (MSymbol) mtext_get_prop (mt, from, Mcharset) : Mnil; - - if (charset == Mcharset_binary) - { - if (first) - { - fprintf (stderr, - "Invalid bytes (at each character position);\n"); - first = 0; - } - for (; from < to; from++) - fprintf (stderr, " 0x%02X(%d)", mtext_ref_char (mt, from), from); - } - else - from = to; - } - if (! first) - fprintf (stderr, "\n"); -} - - -/* Check unencoded characters in the last encoding. Text property - Mcoding of such a character is Mnil. */ - -void -check_unencoded_chars (MText *mt, int len) -{ - int from = 0, to = 0; - int first = 1; - - while (to < len) - { - int n = mtext_prop_range (mt, Mcoding, from, NULL, &to, 1); - MSymbol coding - = n > 0 ? (MSymbol) mtext_get_prop (mt, from, Mcoding) : Mnil; - - if (coding == Mnil) - { - if (first) - { - fprintf (stderr, - "Unencoded characters (at each character position):\n"); - first = 0; - } - for (; from < to; from++) - fprintf (stderr, " 0x%02X(%d)", mtext_ref_char (mt, from), from); - } - else - from = to; - } - if (! first) - fprintf (stderr, "\n"); -} - - -/* Format MSG by FMT and print the result to the stderr, and exit. */ - -#define FATAL_ERROR(fmt, arg) \ - do { \ - fprintf (stderr, fmt, arg); \ - exit (1); \ - } while (0) - - -int -main (int argc, char **argv) -{ - int suppress_warning, verbose, continue_on_error; - MSymbol incode, outcode; - FILE *in, *out; - MText *mt; - MConverter *converter; - int i; - - /* Initialize the m17n library. */ - M17N_INIT (); - if (merror_code != MERROR_NONE) - FATAL_ERROR ("%s\n", "Fail to initialize the m17n library."); - - /* Default encodings are both UTF-8. */ - incode = outcode = Mcoding_utf_8; - /* By default, read from standard input and write to standard output. */ - in = stdin, out = stdout; - /* By default, all these flags are 0. */ - suppress_warning = verbose = continue_on_error = 0; - /* Parse the command line arguments. */ - for (i = 1; i < argc; i++) - { - if (! strcmp (argv[i], "--help") - || ! strcmp (argv[i], "-h") - || ! strcmp (argv[i], "-?")) - help_exit (argv[0], 0); - else if (! strcmp (argv[i], "--version")) - { - printf ("mconv (m17n library) %s\n", VERSION); - printf ("Copyright (C) 2003 AIST, JAPAN\n"); - exit (0); - } - else if (! strcmp (argv[i], "-l")) - { - list_coding (); - M17N_FINI (); - exit (0); - } - else if (! strcmp (argv[i], "-f")) - { - incode = mconv_resolve_coding (msymbol (argv[++i])); - if (incode == Mnil) - FATAL_ERROR ("Unknown encoding: %s\n", argv[i]); - } - else if (! strcmp (argv[i], "-t")) - { - outcode = mconv_resolve_coding (msymbol (argv[++i])); - if (outcode == Mnil) - FATAL_ERROR ("Unknown encoding: %s\n", argv[i]); - } - else if (! strcmp (argv[i], "-k")) - continue_on_error = 1; - else if (! strcmp (argv[i], "-s")) - suppress_warning = 1; - else if (! strcmp (argv[i], "-v")) - verbose = 1; - else if (argv[i][0] != '-') - { - if (in == stdin) - { - in = fopen (argv[i], "r"); - if (! in) - FATAL_ERROR ("Can't read the file %s\n", argv[i]); - } - else if (out == stdout) - { - out = fopen (argv[i], "w"); - if (! out) - FATAL_ERROR ("Can't write the file %s\n", argv[i]); - } - else - help_exit (argv[0], 1); - } - else - help_exit (argv[0], 1); - } - - /* Create an M-text to store the decoded characters. */ - mt = mtext (); - - /* Create a converter for decoding. */ - converter = mconv_stream_converter (incode, in); - /* Instead of doing strict decoding, we decode all input bytes at - once, and check invalid bytes later by the fuction - check_invalid_bytes. */ - converter->lenient = 1; - - mconv_decode (converter, mt); - - if (! suppress_warning) - check_invalid_bytes (mt); - if (verbose) - fprintf (stderr, "%d bytes (%s) decoded into %d characters,\n", - converter->nbytes, msymbol_name (incode), mtext_len (mt)); - - mconv_free_converter (converter); - - /* Create a converter for encoding. */ - converter = mconv_stream_converter (outcode, out); - /* Instead of doing strict encoding, we encode all characters at - once, and check unencoded characters later by the fuction - check_unencoded_chars. */ - converter->lenient = 1; - converter->last_block = 1; - if (mconv_encode (converter, mt) < 0 - && ! suppress_warning) - fprintf (stderr, "I/O error on writing\n"); - if (! suppress_warning) - check_unencoded_chars (mt, converter->nchars); - if (verbose) - fprintf (stderr, "%d characters encoded into %d bytes (%s).\n", - converter->nchars, converter->nbytes, msymbol_name (outcode)); - - /* Clear away. */ - mconv_free_converter (converter); - m17n_object_unref (mt); - M17N_FINI (); - exit (0); -} -#endif /* not FOR_DOXYGEN */ diff --git a/example/mdate.c b/example/mdate.c deleted file mode 100644 index 6f46599..0000000 --- a/example/mdate.c +++ /dev/null @@ -1,215 +0,0 @@ -/* mdate.c -- Show the sysmet date and time in all locales. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -/***en - @page mdate display date and time - - @section mdate-synopsis SYNOPSIS - - mdate [ OPTION ... ] - - @section mdate-description DESCRIPTION - - Display the system date and time in many locales on a window. - - The following OPTIONs are available. - -
    - -
  • --version - - Print version number. - -
  • -h, --help - - Print this message. -
-*/ - -#ifndef FOR_DOXYGEN - -#include -#include -#include -#include -#include -#include - -#include -#include - -#define VERSION "1.0" - -/* Return a plist of all locales currently avairable on the system. - The keys and values of the plist are locale name symbols and - pointers to MLocale respectively. */ - -MPlist * -list_system_locales () -{ - FILE *p; - char buf[1024]; - MPlist *plist; - - /* Run the command "locale -a" to get a list of locales. */ - if (! (p = popen ("locale -a", "r"))) - { - fprintf (stderr, "Can't run `locale -a'.\n"); - exit (1); - } - - plist = mplist (); - /* Read from the pipe one line by one. */ - while (fgets (buf, 1024, p)) - { - MLocale *locale; - int len = strlen (buf); - - if (buf[len - 1] == '\n') - buf[len - 1] = '\0'; - locale = mlocale_set (LC_TIME, buf); - - /* If the locale is surely usable, it is not duplicated, and we - know the corresponding coding system, add it to the list. */ - if (locale - && ! mplist_get (plist, mlocale_get_prop (locale, Mname)) - && mlocale_get_prop (locale, Mcoding) != Mnil) - mplist_add (plist, mlocale_get_prop (locale, Mname), locale); - } - pclose (p); - return plist; -} - - -/* Print the usage of this program (the name is PROG), and exit with - EXIT_CODE. */ - -void -help_exit (char *prog, int exit_code) -{ - char *p = prog; - - while (*p) - if (*p++ == '/') - prog = p; - - printf ("Usage: %s [ OPTION ...]\n", prog); - printf ("Display the system date and time in many locales on a window.\n"); - printf ("The following OPTIONs are available.\n"); - printf (" %-13s %s", "--version", "Print version number.\n"); - printf (" %-13s %s", "-h, --help", "Print this message.\n"); - exit (exit_code); -} - - -/* Format MSG by FMT and print the result to the stderr, and exit. */ - -#define FATAL_ERROR(fmt, arg) \ - do { \ - fprintf (stderr, fmt, arg); \ - exit (1); \ - } while (0) - - -int -main (int argc, char **argv) -{ - time_t current_time_t = time (NULL); - struct tm *current_time_tm = localtime (¤t_time_t); - /* List of all locales. */ - MPlist *locale_list, *plist; - /* Text to be shown. */ - MText *mt; - int i; - - for (i = 1; i < argc; i++) - { - if (! strcmp (argv[i], "--help") - || ! strcmp (argv[i], "-h") - || ! strcmp (argv[i], "-?")) - help_exit (argv[0], 0); - else if (! strcmp (argv[i], "--version")) - { - printf ("mdate (m17n library) %s\n", VERSION); - printf ("Copyright (C) 2003 AIST, JAPAN\n"); - exit (0); - } - else - help_exit (argv[0], 1); - } - - - /* Initialize the m17n library. */ - M17N_INIT (); - if (merror_code != MERROR_NONE) - FATAL_ERROR ("%s\n", "Fail to initialize the m17n library."); - - /* Get a local list in LOCALE_LIST, and generate an M-text that - contains date string in each locale. */ - locale_list = list_system_locales (); - mt = mtext (); - plist = locale_list; - while (mplist_key (plist) != Mnil) - { - char *name = msymbol_name (mplist_key (plist)); - char fmtbuf[256]; - int len; - MLocale *locale = mplist_value (plist); - MSymbol coding = mlocale_get_prop (locale, Mcoding); - /* One line text for this locale. The format is: - "LOCALE-NAME: DATE-AND-TIME-STRING". */ - MText *thisline; - - sprintf (fmtbuf, "%16s: ", name); - len = strlen (fmtbuf); - thisline = mconv_decode_buffer (coding, (unsigned char *) fmtbuf, len); - if (thisline) - { - mlocale_set (LC_TIME, name); - if (mtext_ftime (thisline, "%c", current_time_tm, NULL) > 0) - { - mtext_cat_char (thisline, '\n'); - mtext_cat (mt, thisline); - } - m17n_object_unref (thisline); - } - plist = mplist_next (plist); - } - - /* Show the generated M-text by another example program "mview". */ - { - FILE *p = popen ("mview", "w"); - - if (!p) - FATAL_ERROR ("%s\n", "Can't run the program mview!"); - mconv_encode_stream (Mcoding_utf_8, mt, p); - fclose (p); - } - - /* Clear away. */ - m17n_object_unref (locale_list); - m17n_object_unref (mt); - M17N_FINI (); - - exit (0); -} -#endif /* not FOR_DOXYGEN */ diff --git a/example/mdump.c b/example/mdump.c deleted file mode 100644 index c402338..0000000 --- a/example/mdump.c +++ /dev/null @@ -1,605 +0,0 @@ -/* mdump.c -- Dump text image - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -/***en - @page mdump dump text image - - @section mdump-synopsis SYNOPSIS - - mdump [ OPTION ... ] [ FILE ] - - @section mdump-description DESCRIPTION - - Dump a text as a Netpbm image. - - The Netpbm image is written to a file created in the current - directory with the name "BASE.pbm" where BASE is the basename of - FILE. If FILE is omitted, text is read from standard input, and - the image is dumped into the file "output.pbm". - - The following OPTIONs are available. - -
    - -
  • -s SIZE - - SIZE is the font size in point. The default font size is 12 point. - -
  • -d DPI - - DPI is the resolution in dots per inch. The default resolution is - 300 dpi. - -
  • -p PAPER - - PAPER is the paper size: a4, a4r, a5, a5r, b5, b5r, letter, or - WxH. In the last case, W and H are the width and height in - millimeter. If this option is specified, PAPER limits the image - size. If FILE is too large for a single page, multiple files with - the names "BASE.01.pbm", "BASE.02.pbm", etc. are created. - -
  • -m MARGIN - - MARGIN is the horizontal and vertical margin in millimeter. The - default margin is 20 mm. It is ignored when PAPER is not - specified. - -
  • -c POS - - POS is the character position of cursor to draw. By default, - cursor is not drawn. - -
  • -x - - FILE is assumed to be an XML file generated by the serialize - facility of the m17n library, and FILE is deserialized before the - image is created. - -
  • -w - - Each line is broken at word boundary. - -
  • -f FILTER - - FILTER is a string containing a shell command line. If this - option is specified, the Netpbm image is not written info a - file but is given to FILTER as standard input. If FILTER - contains "%s", that part is replaced by a basename of FILE. - So, the default behaviour is the same as specifying "cat > - %s.pbm" as FILTER. - -
  • -q - - Quiet mode. Don't print any messages. - -
  • --version - - Print the version number. - -
  • -h, --help - - Print this message. - -
-*/ - -#ifndef FOR_DOXYGEN - -#include -#include -#include -#include - -#include - -#include -#include - -#define VERSION "1.0" - -/* Enumuration of the supported paper types. */ -enum paper_type - { - PAPER_A4, - PAPER_A4R, - PAPER_A5, - PAPER_A5R, - PAPER_B5, - PAPER_B5R, - PAPER_LETTER, - PAPER_USER, - PAPER_NOLIMIT - }; - -/* Array of paper sizes for the supported paper types. */ -struct -{ - int width, height; /* in millimeter */ -} paper_size[PAPER_NOLIMIT] = { - { 210, 297 }, /* a4 */ - { 297, 210 }, /* a4r */ - { 148, 210 }, /* a5 */ - { 210, 148 }, /* a5r */ - { 250, 176 }, /* b5 */ - { 176, 250 }, /* b5r */ - { 216, 279 }, /* letter */ -}; - - -/* Print the usage of this program (the name is PROG), and exit with - EXIT_CODE. */ - -void -help_exit (char *prog, int exit_code) -{ - char *p = prog; - - while (*p) - if (*p++ == '/') - prog = p; - - printf ("Usage: %s [ OPTION ...] [ FILE ]\n", prog); - printf ("Dump a text as a Netpbm image into a PBM file.\n"); - printf (" The PBM file is created in the current directory\n"); - printf (" with the name \"BASE.pbm\" where BASE is the basename of FILE.\n"); - printf (" If FILE is omitted, text is read from standard input, and\n"); - printf (" dumped into the file \"output.pbm\".\n"); - printf ("The following OPTIONs are available.\n"); - printf (" %-13s %s", "-s SIZE", - "Font size in point (default 12).\n"); - printf (" %-13s %s", "-d DPI", - "Resolution in dots per inch (defualt 300).\n"); - printf (" %-13s %s", "-p PAPER", - "Paper size; a4, a4r, a5, a5r, b5, b5r, letter, or WxH.\n"); - printf (" %-13s %s", "-m MARGIN", - "Marginal space in millimeter (default 20).\n"); - printf (" %-13s %s", "-c POS", - "Character position of cursor to draw (default no cursor)\n"); - printf (" %-13s %s", "-x", - "FILE is assumed to be an XML file.\n"); - printf (" %-13s %s", "-f FILTER", - "String containing a shell command line to be used as a filter.\n"); - printf (" %-13s %s", "-w", "Each line is broken at word boundary.\n"); - printf (" %-13s %s", "-q", "Quiet mode. Don't print any messages.\n"); - printf (" %-13s %s", "--version", "Print the version number.\n"); - printf (" %-13s %s", "-h, --help", "Print this message.\n"); - exit (exit_code); -} - - -/* Format MSG by FMT and print the result to the stderr, and exit. */ - -#define FATAL_ERROR(fmt, arg) \ - do { \ - fprintf (stderr, fmt, arg); \ - exit (1); \ - } while (0) - - -/* Move POS to the next line head in M-text MT whose length is LEN. - If POS is already on the last line, set POS to LEN. */ - -#define NEXTLINE(pos, len) \ - do { \ - pos = mtext_character (mt, pos, len, '\n'); \ - if (pos < 0) \ - pos = len; \ - else \ - pos++; \ - } while (0) - - -/* Find the range of M-text MT that fits in one page of height HEIGHT - when drawn from the character position POS. Set RECT->y to the - Y-offset of the first baseline. */ - -int -find_page_end (MFrame *frame, int height, MText *mt, int pos, - MDrawControl *control, MDrawMetric *rect) -{ - int len = mtext_len (mt); - int to = pos; - int y = 0, yoff; - - while (to < len) - { - int next = to; - - NEXTLINE (next, len); - mdraw_text_extents (frame, mt, to, next, control, NULL, NULL, rect); - if (to == pos) - yoff = rect->y; - if (y + rect->height > height) - { - MDrawGlyphInfo info; - - while (to < next) - { - mdraw_glyph_info (frame, mt, to, to, control, &info); - if (y + info.this.height > height) - break; - y += info.this.height; - to = info.line_to; - } - break; - } - y += rect->height; - to = next; - } - - rect->y = yoff; - return to; -} - - -/* Table to convert a byte of LSBFirst to MSBFirst. */ -char reverse_bit_order[256]; - -/* Initialize the above table. */ - -void -init_reverse_bit_order () -{ - int i; - - for (i = 0; i < 256; i++) - reverse_bit_order[i] - = (((i & 1) << 7) | ((i & 2) << 5) | ((i & 4) << 3) | ((i & 8) << 1) - | ((i & 16) >> 1) | ((i & 32) >> 3) - | ((i & 64) >> 5) | ((i & 128) >> 7)); -} - - -/* Dump the image in IMAGE into a file whose name is generated from - FILENAME and PAGE_INDEX (if it is not zero). */ - -void -dump_image (XImage *image, char *filename, char *filter, - int white_is_zero, int page_index, int quiet_mode) -{ - FILE *fp; - int pbm_bytes_per_line; - char *data = image->data; - int x, y; - - if (page_index) - { - char *name = alloca (strlen (filename) + 8); - - sprintf (name, "%s.%02d", filename, page_index); - filename = name; - } - - if (filter) - { - char *command = alloca (strlen (filename) + strlen (filter) + 1); - - sprintf (command, filter, filename); - fp = popen (command, "w"); - if (! fp) - FATAL_ERROR ("Can't run the command \"%s\"\n", command); - if (! quiet_mode) - printf ("Running \"%s\" ... ", command); - } - else - { - char *fullname = alloca (strlen (filename) + 5); - - sprintf (fullname, "%s.pbm", filename); - fp = fopen (fullname, "w"); - if (! fp) - FATAL_ERROR ("Can't write to \"%s\"\n", fullname); - if (! quiet_mode) - printf ("Writing %s ... ", fullname); - } - - if (image->bitmap_bit_order != MSBFirst - || (image->byte_order != MSBFirst - && image->bitmap_unit != 8)) - { - /* We must adjust image->data for PBM. */ - int bytes_per_unit = image->bitmap_unit / 8; - - for (y = 0; y < image->height; y++, data += image->bytes_per_line) - { - char b; - - if (image->byte_order != MSBFirst) - { - if (reverse_bit_order[0] == 0) - init_reverse_bit_order (); - if (bytes_per_unit == 2) - for (x = 0; x < image->bytes_per_line; x += 2) - b = data[x], data[x] = data[x + 1], data[x + 1] = b; - else if (bytes_per_unit == 6) - for (x = 0; x < image->bytes_per_line; x += 3) - { - b = data[x], data[x] = data[x + 3], data[x + 3] = b; - x++; - b = data[x], data[x] = data[x + 1], data[x + 1] = b; - } - } - - if (image->bitmap_bit_order != MSBFirst) - for (x = 0; x < image->bytes_per_line; x++) - data[x] = reverse_bit_order[(unsigned char) data[x]]; - if (! white_is_zero) - for (x = 0; x < image->bytes_per_line; x++) - data[x] = ~data[x]; - } - /* Reset DATA. */ - data = image->data; - } - - /* Generate PBM (Portable Bitmap File Format) of P4 format. */ - fprintf (fp, "P4\n%d %d\n", image->width, image->height); - pbm_bytes_per_line = (image->width + 7) / 8; - for (y = 0; y < image->height; y++, data += image->bytes_per_line) - fwrite (data, 1, pbm_bytes_per_line, fp); - - fclose (fp); - if (! quiet_mode) - printf (" done (%dx%d)\n", image->width, image->height); -} - -extern int line_break (MText *mt, int pos, int from, int to, int line, int y); - -int -main (int argc, char **argv) -{ - Display *display; - int screen; - GC gc; - Pixmap pixmap; - XImage *image; - int fontsize = 120; - int paper = PAPER_NOLIMIT; - int dpi = 300; - int margin = 20; - int xml = 0; - FILE *fp = stdin; - int cursor_pos = -1; - int quiet_mode = 0; - int break_by_word = 0; - char *filter = NULL; - int i; - int paper_width, paper_height; - int page_index; - - MFrame *frame; - MText *mt; - MDrawControl control; - MDrawMetric rect; - char *filename = "output"; - int len, from; - - /* Parse the command line arguments. */ - for (i = 1; i < argc; i++) - { - if (! strcmp (argv[i], "--help") - || ! strcmp (argv[i], "-h") - || ! strcmp (argv[i], "-?")) - help_exit (argv[0], 0); - else if (! strcmp (argv[i], "--version")) - { - printf ("mdump (m17n library) %s\n", VERSION); - printf ("Copyright (C) 2003, 2004 AIST, JAPAN\n"); - exit (0); - } - else if (! strcmp (argv[i], "-s") && i + 1< argc) - { - fontsize = atoi (argv[++i]); - if (! fontsize) - FATAL_ERROR ("Invalid font size: %s\n", argv[i]); - } - else if (! strcmp (argv[i], "-p") && i + 1< argc) - { - int w, h; - - i++; - if (! strcmp (argv[i], "a4")) - paper = PAPER_A4; - else if (! strcmp (argv[i], "a4r")) - paper = PAPER_A4R; - else if (! strcmp (argv[i], "a5")) - paper = PAPER_A5; - else if (! strcmp (argv[i], "a5r")) - paper = PAPER_A5R; - else if (! strcmp (argv[i], "b5")) - paper = PAPER_B5; - else if (! strcmp (argv[i], "b5r")) - paper = PAPER_B5R; - else if (! strcmp (argv[i], "letter")) - paper = PAPER_LETTER; - else if (sscanf (argv[i], "%dx%d", &w, &h) == 2 - && w > 0 && h > 0) - { - paper = PAPER_USER; - paper_size[paper].width = w; - paper_size[paper].height = h; - } - else - FATAL_ERROR ("Invalid paper type: %s\n", argv[i]); - } - else if (! strcmp (argv[i], "-d") && i + 1< argc) - { - dpi = atoi (argv[++i]); - if (! dpi) - FATAL_ERROR ("Invalid resolution: %s\n", argv[i]); - } - else if (! strcmp (argv[i], "-m") && i + 1< argc) - { - margin = atoi (argv[++i]); - if (margin < 0) - FATAL_ERROR ("Invalid margin: %s\n", argv[i]); - } - else if (! strcmp (argv[i], "-c") && i + 1< argc) - { - cursor_pos = atoi (argv[++i]); - if (cursor_pos < 0) - FATAL_ERROR ("Invalid cursor position: %s\n", argv[i]); - } - else if (! strcmp (argv[i], "-f") && i + 1< argc) - { - filter = argv[++i]; - } - else if (! strcmp (argv[i], "-x")) - { - xml = 1; - } - else if (! strcmp (argv[i], "-w")) - { - break_by_word = 1; - } - else if (! strcmp (argv[i], "-q")) - { - quiet_mode = 1; - } - else if (argv[i][0] != '-') - { - fp = fopen (argv[i], "r"); - if (! fp) - FATAL_ERROR ("Fail to open the file %s!\n", argv[i]); - filename = basename (argv[i]); - } - else - { - fprintf (stderr, "Unknown or invalid option: %s\n", argv[i]); - help_exit (argv[0], 1); - } - } - - /* Initialize the m17n library. */ - M17N_INIT (); - if (merror_code != MERROR_NONE) - FATAL_ERROR ("%s\n", "Fail to initialize the m17n library."); - - mt = mconv_decode_stream (Mcoding_utf_8, fp); - fclose (fp); - if (xml) - mt = mtext_deserialize (mt); - if (! mt) - FATAL_ERROR ("%s\n", "Fail to decode the input file or stream!"); - - len = mtext_len (mt); - - if (paper == PAPER_NOLIMIT) - paper_width = paper_height = margin = 0; - else - { - paper_width = paper_size[paper].width * dpi / 25.4; - paper_height = paper_size[paper].height * dpi / 25.4; - margin = margin * dpi / 25.4; - } - - display = XOpenDisplay (NULL); - screen = DefaultScreen (display); - - { - MPlist *plist = mplist (), *p; - MFontset *fontset = mfontset ("truetype"); - MFace *face = mface (); - - mface_put_prop (face, Mfontset, fontset); - mface_put_prop (face, Msize, (void *) (fontsize * dpi / 100)); - p = mplist_add (plist, msymbol ("display"), display); - p = mplist_add (p, msymbol ("depth"), (void *) 1); - p = mplist_add (p, Mface, face); - m17n_object_unref (face); - frame = mframe (plist); - m17n_object_unref (plist); - if (! frame) - FATAL_ERROR ("%s\n", "Can't open a frame (perhaps no font avairable)!"); - } - - memset (&control, 0, sizeof control); - control.as_image = 1; - control.two_dimensional = 1; - control.enable_bidi = 1; - if (cursor_pos >= 0) - { - control.with_cursor = 1; - if (cursor_pos > len) - cursor_pos = len; - control.cursor_pos = cursor_pos; - control.cursor_width = -1; - } - else - control.ignore_formatting_char = 1; - if (break_by_word) - control.line_break = line_break; - - if (paper == PAPER_NOLIMIT) - { - control.max_line_width = 0; - mdraw_text_extents (frame, mt, 0, len, &control, NULL, NULL, &rect); - paper_width = rect.width; - paper_height = rect.height; - } - else - control.max_line_width = paper_width - margin * 2; - - pixmap = XCreatePixmap (display, RootWindow (display, screen), - paper_width, paper_height, 1); - gc = XCreateGC (display, pixmap, 0L, NULL); - - from = 0; - page_index = 1; - while (from < len) - { - int to; - - if (paper == PAPER_NOLIMIT) - to = len; - else - to = find_page_end (frame, paper_height - margin * 2, mt, from, - &control, &rect); - - XSetForeground (display, gc, WhitePixel (display, screen)); - XFillRectangle (display, pixmap, gc, 0, 0, paper_width, paper_height); - mdraw_text_with_control (frame, (MDrawWindow) pixmap, - margin, margin - rect.y, mt, from, to, - &control); - XSetForeground (display, gc, BlackPixel (display, screen)); -#if 0 - XDrawRectangle (display, pixmap, gc, margin, margin, - paper_width - margin * 2 - 1, - paper_height - margin * 2 - 1); -#endif - image = XGetImage (display, pixmap, 0, 0, paper_width, paper_height, - AllPlanes, XYPixmap); - XInitImage (image); - dump_image (image, filename, filter, !WhitePixel (display, screen), - ((from > 0 || to < len) ? page_index : 0), - quiet_mode); - - from = to; - page_index++; - } - - m17n_object_unref (frame); - m17n_object_unref (mt); - M17N_FINI (); - XCloseDisplay (display); - exit (0); -} -#endif /* not FOR_DOXYGEN */ diff --git a/example/medit.c b/example/medit.c deleted file mode 100644 index eb30560..0000000 --- a/example/medit.c +++ /dev/null @@ -1,2700 +0,0 @@ -/* medit.c -- simple multilingual editor. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -/***en - @page medit edit multilingual text - - @section medit-synopsis SYNOPSIS - - medit [ XT-OPTION ...] [ OPTION ... ] FILE - - @section medit-description DESCRIPTION - - Display FILE on a window and allow users to edit it. - - XT-OPTIONs are standard Xt arguments (e.g. -fn, -fg). - - The following OPTIONs are available. - -
    - -
  • --version - - Print version number. - -
  • -h, --help - - Print this message. - -
- - This program is to demonstrate how to use the m17n GUI API. - Although medit directly uses the GUI API, the API is mainly for - toolkit libraries or to implement XOM (X Outout Method), not for - direct use from application programs. -*/ - -#ifndef FOR_DOXYGEN - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define VERSION "1.0" - -/* Global variables. */ - -char *filename; -int serialized; - -/* For the X Window System. */ -Display *display; -int screen; -/* GCs for normal drawing, filling by background color, normal drawing - on bitmap (i.e. pixmap of depth 1), filling bitmap by background - color. */ -GC gc, gc_inv, mono_gc, mono_gc_inv; -Window win; -Atom XA_TEXT, XA_COMPOUND_TEXT, XA_UTF8_STRING; /* X Selection types. */ -XtAppContext context; -int default_font_size; - -/* Widget hierarchy - -Shell - Form -+- Head -- File, Cursor, Bidi, LineBreak, InputMethod, CurIM; - +- Face -- Size, Family, Style, Color, Misc, Pop, CurFace - +- Lang -- A-B, C-D, ..., U-Z, Pop, CurLang - +- Body -- Sbar, Text - +- Tail -- Message -*/ - -Widget ShellWidget, HeadWidget, TailWidget, MessageWidget; -Widget CursorMenus[5], BidiMenus[3], LineBreakMenus[3], *InputMethodMenus; -Widget SbarWidget, TextWidget; -Widget FileShellWidget, FileDialogWidget; -Widget FaceWidget, CurFaceWidget, LangWidget, CurLangWidget; -Widget CurIMLang, CurIMStatus; - -int win_width, win_height; /* Size of TextWidget. */ -Arg arg[10]; - -Pixmap input_status_pixmap; -int input_status_width, input_status_height; - -/* Bitmap for "check" glyph. */ -#define check_width 9 -#define check_height 8 -static unsigned char check_bits[] = { - 0x00, 0x01, 0x80, 0x01, 0xc0, 0x00, 0x60, 0x00, - 0x31, 0x00, 0x1b, 0x00, 0x0e, 0x00, 0x04, 0x00 }; -Pixmap CheckPixmap; - -/* For the m17n library. */ -MFrame *frame; -MText *mt; -int nchars; /* == mtext_len (mt) */ -MDrawControl control; -MTextProperty *selection; - -MFace *face_default; -MFace *face_xxx_large; -MFace *face_box; -MFace *face_courier, *face_helvetica, *face_times; -MFace *face_dv_ttyogesh, *face_freesans, *face_freemono; -MFace *face_default_fontset, *face_no_ctl_fontset; -MFace *face_input_status; - -int logical_move = 1; /* If 0, move cursor visually. */ - -MInputMethod **input_method_table; -int num_input_methods; -int current_input_method = -1; /* i.e. none */ -int auto_input_method = 0; -MInputContext *current_input_context; - -struct FaceRec -{ - char *name; - MFace **face; -} face_table[] = - { {"Menu Size", NULL}, - {"xx-small", &mface_xx_small}, - {"x-small", &mface_x_small}, - {"small", &mface_small}, - {"normalsize", &mface_normalsize}, - {"large", &mface_large}, - {"x-large", &mface_x_large}, - {"xx-large", &mface_xx_large}, - {"xxx-large", &face_xxx_large}, - - {"Menu Family", NULL}, - {"courier", &face_courier}, - {"helvetica", &face_helvetica}, - {"times", &face_times}, - {"dv-ttyogesh", &face_dv_ttyogesh}, - {"freesans", &face_freesans}, - {"freemono", &face_freemono}, - - {"Menu Style", NULL}, - {"medium", &mface_medium}, - {"bold", &mface_bold}, - {"italic", &mface_italic}, - - {"Menu Color", NULL}, - {"black", &mface_black}, - {"white", &mface_white}, - {"red", &mface_red}, - {"green", &mface_green}, - {"blue", &mface_blue}, - {"cyan", &mface_cyan}, - {"yello", &mface_yellow}, - {"magenta", &mface_magenta}, - - {"Menu Misc", NULL}, - {"normal", &mface_normal_video}, - {"reverse", &mface_reverse_video}, - {"underline", &mface_underline}, - {"box", &face_box}, - {"No CTL", &face_no_ctl_fontset} }; - - -int num_faces = sizeof (face_table) / sizeof (struct FaceRec); - -/* Information about a physical line metric. */ -struct LineInfo -{ - int from; /* BOL position of the line. */ - int to; /* BOL position of the next line. */ - int y0, y1; /* Top and bottom Y position of the line. */ - int ascent; /* Height of the top Y position. */ -}; - -struct LineInfo top; /* Topmost line. */ -struct LineInfo cur; /* Line containing cursor. */ -struct LineInfo sel_start; /* Line containing selection start. */ -struct LineInfo sel_end; /* Line containing selection end. */ - -MDrawGlyphInfo cursor; /* Information about the cursor glyph. */ - -/* X position to keep on vertical (up and down) cursor motion. */ -int target_x_position; - -/* Interface macros for m17n-lib drawing routines. */ - -/* Draw a text in the range $FROM to $TO of the M-text #MT at the - coordinate ($X, $Y) */ -#define DRAW_TEXT(x, y, from, to) \ - mdraw_text_with_control \ - (frame, (MDrawWindow) win, \ - control.orientation_reversed ? x + win_width : x, y, \ - mt, from, to, &control) - -/* Store the extents of a text in the range $FROM to $TO in the - structure $RECT (type MDrawMetric). */ -#define TEXT_EXTENTS(from, to, rect) \ - mdraw_text_extents (frame, mt, from, (to), &control, NULL, NULL, &(rect)) - -/* Store the glyph information of a character at the position $POS in - the struct $INFO (type MDrawGlyphInfo) assuming that the text from - $FROM is written at the coordinate (0, 0). */ -#define GLYPH_INFO(from, pos, info) \ - mdraw_glyph_info (frame, mt, from, (pos), &control, &(info)) - -/* Set $X and $Y to the coordinate of character at position $POS - assuming that the text from $FROM is written at the coordinate (0, - 0). */ -#define COORDINATES_POSITION(from, pos, x, y) \ - mdraw_coordinates_position (frame, mt, (from), (pos), (x), (y), &control) - -/* Interface macros for X library. */ -#define COPY_AREA(y0, y1, to) \ - XCopyArea (display, win, win, gc, 0, (y0), win_width, (y1) - (y0), 0, (to)) - -#define CLEAR_AREA(x, y, w, h) \ - XClearArea (display, win, (x), (y), (w), (h), False) - -#define SELECTEDP() \ - mtext_property_mtext (selection) - -/* Format MSG by FMT and print the result to the stderr, and exit. */ -#define FATAL_ERROR(fmt, arg) \ - do { \ - fprintf (stderr, fmt, arg); \ - exit (1); \ - } while (0) - - -/* If POS is greater than zero, move POS back to the beginning of line - (BOL) position. If FORWARD is nonzero, move POS forward instead. - Return the new position. */ -int -bol (int pos, int forward) -{ - int limit = forward ? nchars : 0; - - pos = mtext_character (mt, pos, limit, '\n'); - return (pos < 0 ? limit : pos + 1); -} - -/* Update the structure #TOP (struct LineInfo) to make $POS the first - character position of the screen. */ -void -update_top (int pos) -{ - int from = bol (pos, 0); - MDrawGlyphInfo info; - - GLYPH_INFO (from, pos, info); - top.from = info.line_from; - top.to = info.line_to; - top.y0 = 0; - top.y1 = info.this.height; - top.ascent = - info.this.y; -} - - -/* Update the scroll bar so that the text of the range $FROM to $TO - are shown on the window. */ -void -update_scroll_bar (int from, int to) -{ - float top = (float) from / nchars; - float shown = (float) (to - from) / nchars; - XtArgVal *l_top = (XtArgVal *) ⊤ - XtArgVal *l_shown = (XtArgVal *) &shown; - - XtSetArg (arg[0], XtNtopOfThumb, *l_top); - XtSetArg (arg[1], XtNshown, *l_shown); - XtSetValues (SbarWidget, arg, 2); -} - - -/* Redraw the window area between $Y0 and $Y1 (both Y-codinates). If - $CLEAR is nonzero, clear the area before drawing. If $SCROLL_BAR - is nonzero, update the scoll bar. */ -void -redraw (int y0, int y1, int clear, int scroll_bar) -{ - int from, to; - int y; - MDrawGlyphInfo info; - int sel_y0 = SELECTEDP () ? sel_start.y0 : 0; - struct LineInfo *line; - - if (clear) - CLEAR_AREA (0, y0, win_width, y1 - y0); - - /* Find a line closest to y0. The lihe is a cursor line if the - cursor is at the position above Y0, otherwise the top line. */ - if (y0 >= cur.y0) - line = &cur; - else - line = ⊤ - /* If there exists a selected region, check it too. */ - if (sel_y0 > line->y0 && y0 >= sel_y0) - line = &sel_start; - - from = line->from; - y = line->y0; - info.this.height = line->y1 - y; - info.this.y = - line->ascent; - info.line_to = line->to; - while (from < nchars && y + info.this.height <= y0) - { - y += info.this.height; - from = info.line_to; - GLYPH_INFO (from, from, info); - } - y0 = y - info.this.y; - to = from; - while (to < nchars && y < y1) - { - GLYPH_INFO (to, to, info); - y += info.this.height; - to = info.line_to; - } - if (to == nchars) - to++; - if (from < to) - DRAW_TEXT (0, y0, from, to); - if (scroll_bar) - { - while (to < nchars) - { - GLYPH_INFO (to, to, info); - if (y + info.this.height >= win_height) - break; - to = info.line_to; - y += info.this.height; - } - update_scroll_bar (top.from, to); - } -} - - -/* Set the current input method spot to the correct position. */ -void -set_input_method_spot () -{ - int x = cursor.x + (control.orientation_reversed ? win_width : 0); - int pos = cursor.from > 0 ? cursor.from - 1 : 0; - MFace *faces[256]; - int n = mtext_get_prop_values (mt, pos, Mface, (void **) faces, 256); - int size = 0, ratio = 0, i; - - for (i = n - 1; i >= 0; i--) - { - if (! size) - size = (int) mface_get_prop (faces[i], Msize); - if (! ratio) - ratio = (int) mface_get_prop (faces[i], Mratio); - } - if (! size) - size = default_font_size; - if (ratio) - size = size * ratio / 100; - minput_set_spot (current_input_context, x, cur.y0 + cur.ascent, - cur.ascent, cur.y1 - (cur.y0 + cur.ascent), size, - mt, cursor.from); -} - - -/* Redraw the cursor. If $CLEAR is nonzero, clear the cursor area - before drawing. */ -void -redraw_cursor (int clear) -{ - if (control.cursor_bidi) - { - /* We must update the whole line of the cursor. */ - int beg = bol (cur.from, 0); - int end = bol (cur.to - 1, 1); - MDrawMetric rect; - int y0 = cur.y0, y1 = cur.y1; - - if (beg != cur.from) - { - TEXT_EXTENTS (beg, cur.from, rect); - y0 -= rect.height; - } - if (end != cur.to) - { - TEXT_EXTENTS (cur.to, end, rect); - y1 += rect.height; - } - redraw (y0, y1, clear, 0); - } - else - { - if (clear) - { - int x = cursor.x; - - if (control.orientation_reversed) - x += win_width - cursor.this.width; - CLEAR_AREA (x, cur.y0, cursor.this.width, cursor.this.height); - } - DRAW_TEXT (cursor.x, cur.y0 + cur.ascent, cursor.from, cursor.to); - } -} - - -/* Update the information about the location of cursor to the position - $POS. If $FULL is nonzero, update the information fully only from - the information about the top line. Otherwise, truct the current - information in the structure $CUR. */ -void -update_cursor (int pos, int full) -{ - MDrawMetric rect; - - if (full) - { - /* CUR is inaccurate. We can trust only TOP. */ - GLYPH_INFO (top.from, pos, cursor); - cur.y0 = top.ascent + cursor.y + cursor.this.y; - } - else if (pos < cur.from) - { - int from = bol (pos, 0); - - TEXT_EXTENTS (from, cur.from, rect); - GLYPH_INFO (from, pos, cursor); - cur.y0 -= (rect.height + rect.y) - (cursor.y + cursor.this.y); - } - else if (pos < cur.to) - { - GLYPH_INFO (cur.from, pos, cursor); - } - else - { - GLYPH_INFO (cur.from, pos, cursor); - cur.y0 += cur.ascent + cursor.y + cursor.this.y; - } - - cur.from = cursor.line_from; - cur.to = cursor.line_to; - cur.y1 = cur.y0 + cursor.this.height; - cur.ascent = - cursor.this.y; -} - - -/* Update the information about the selected region. */ -void -update_selection () -{ - int from, to; - MDrawMetric rect; - MDrawGlyphInfo info; - - if (! SELECTEDP ()) - return; - from = mtext_property_start (selection); - to = mtext_property_end (selection); - - if (from < top.from) - { - GLYPH_INFO (bol (from, 0), from, info); - sel_start.ascent = -info.this.y; - sel_start.from = info.line_from; - sel_start.to = info.line_to; - TEXT_EXTENTS (from, top.from, rect); - sel_start.y0 = - rect.height; - sel_start.y1 = sel_start.y0 + info.this.height; - } - else - { - GLYPH_INFO (top.from, from, info); - sel_start.y0 = top.ascent + info.y + info.this.y; - sel_start.y1 = sel_start.y0 + info.this.height; - sel_start.ascent = -info.this.y; - sel_start.from = info.line_from; - sel_start.to = info.line_to; - } - - if (to <= sel_start.to) - { - sel_end = sel_start; - to = bol (to - 1, 1) - 1; - if (to >= sel_end.to) - { - GLYPH_INFO (sel_start.from, to, info); - sel_end.y1 = sel_end.y0 + info.y + info.this.height; - sel_end.to = info.line_to; - } - } - else - { - to = bol (to - 1, 1) - 1; - GLYPH_INFO (sel_start.from, to, info); - sel_end.y0 = sel_start.y0 + sel_start.ascent + info.y + info.this.y; - sel_end.y1 = sel_end.y0 + info.this.height; - sel_end.ascent = - info.this.y; - sel_end.from = info.line_from; - sel_end.to = info.line_to; - } -} - - -/* Select the text in the region from $FROM to $TO. */ -void -select_region (int from, int to) -{ - int pos; - - if (from > to) - pos = from, from = to, to = pos; - mtext_push_property (mt, from, to, selection); - update_selection (); -} - - -/* Setup the window to display the character of $POS at the top left - of the window. */ -void -reseat (int pos) -{ - MDrawMetric rect; - /* Top and bottom Y positions to redraw. */ - int y0, y1; - - if (pos + 1000 < top.from) - y0 = 0, y1 = win_height; - else if (pos < top.from) - { - y0 = 0; - TEXT_EXTENTS (pos, top.from, rect); - if (rect.height >= win_height * 0.9) - y1 = win_height; - else - { - y1 = rect.height; - COPY_AREA (0, win_height - y1, y1); - } - } - else if (pos < top.to) - { - /* No need of redrawing. */ - y0 = y1 = 0; - } - else if (pos < top.from + 1000) - { - TEXT_EXTENTS (top.from, pos, rect); - if (rect.height >= win_height * 0.9) - y0 = 0; - else - { - y0 = win_height - rect.height; - COPY_AREA (rect.height, win_height, 0); - } - y1 = win_height; - } - else - y0 = 0, y1 = win_height; - - if (y0 < y1) - { - update_top (pos); - if (cur.to <= pos) - update_cursor (pos, 1); - else - update_cursor (cursor.from, 1); - update_selection (); - redraw (y0, y1, 1, 1); - } -} - -static void MenuHelpProc (Widget, XEvent *, String *, Cardinal *); - - -/* Select an input method accoding to $IDX. If $IDX is negative, turn - off the current input method, otherwide turn on the input method - input_method_table[$IDX]. */ -void -select_input_method (idx) -{ - if (idx == current_input_method) - return; - if (current_input_context) - { - minput_destroy_ic (current_input_context); - current_input_context = NULL; - current_input_method = -1; - } - if (idx >= 0) - { - MInputMethod *im = input_method_table[idx]; - - if (im->language == Mnil) - { - MInputXIMArgIC arg_xic; - Window win = XtWindow (TextWidget); - - arg_xic.input_style = 0; - arg_xic.client_win = arg_xic.focus_win = win; - arg_xic.preedit_attrs = arg_xic.status_attrs = NULL; - current_input_context = minput_create_ic (im, &arg_xic); - } - else - { - MInputGUIArgIC arg_ic; - - arg_ic.frame = frame; - arg_ic.client = (MDrawWindow) XtWindow (ShellWidget); - arg_ic.focus = (MDrawWindow) XtWindow (TextWidget); - current_input_context = minput_create_ic (im, &arg_ic); - } - - if (current_input_context) - { - set_input_method_spot (); - current_input_method = idx; - } - } - if (current_input_method >= 0) - { - char *label; - XtSetArg (arg[0], XtNlabel, &label); - XtGetValues (InputMethodMenus[current_input_method + 2], arg, 1); - XtSetArg (arg[0], XtNlabel, label); - } - else - XtSetArg (arg[0], XtNlabel, ""); - XtSetValues (CurIMLang, arg, 1); -} - -static void MenuHelpProc (Widget w, XEvent *event, String *str, Cardinal *num); - - -/* Display cursor according to the current information of #CUR. - $CLIENT_DATA is ignore. Most callback functions add this function - as a background processing procedure the current application (by - XtAppAddWorkProc) via the function hide_cursor. */ -Boolean -show_cursor (XtPointer client_data) -{ - if (cur.y0 < 0) - { - reseat (cur.from); - update_cursor (cursor.from, 1); - } - while (cur.y1 > win_height) - { - reseat (top.to); - update_cursor (cursor.from, 1); - } - - control.cursor_pos = cursor.from; - if (! SELECTEDP ()) - { - control.with_cursor = 1; - redraw_cursor (0); - } - if (current_input_context) - set_input_method_spot (); - - { - int pos = (SELECTEDP () ? mtext_property_start (selection) - : cursor.from > 0 ? cursor.from - 1 - : cursor.from); - MFace *face = mface (); - MTextProperty *props[256]; - int n = mtext_get_properties (mt, pos, Mface, props, 256); - int i; - char buf[256], *p = buf; - MSymbol sym; - - buf[0] = '\0'; - if (cursor.font) - { - int size = (int) mfont_get_prop (cursor.font, Msize); - MSymbol family = mfont_get_prop (cursor.font, Mfamily); - MSymbol weight = mfont_get_prop (cursor.font, Mweight); - MSymbol style = mfont_get_prop (cursor.font, Mstyle); - MSymbol registry = mfont_get_prop (cursor.font, Mregistry); - - sprintf (p, "%dpt", size / 10), p += strlen (p); - if (family) - strcat (p, ","), strcat (p, msymbol_name (family)), p += strlen (p); - if (weight) - strcat (p, ","), strcat (p, msymbol_name (weight)), p += strlen (p); - if (style) - strcat (p, ","), strcat (p, msymbol_name (style)), p += strlen (p); - if (registry) - strcat (p, ","), strcat (p, msymbol_name (registry)), p += strlen (p); - p += strlen (p); - } - - mface_merge (face, face_default); - for (i = 0; i < n; i++) - if (props[i] != selection) - mface_merge (face, (MFace *) mtext_property_value (props[i])); - sym = (MSymbol) mface_get_prop (face, Mforeground); - if (sym != Mnil) - strcat (p, ","), strcat (p, msymbol_name (sym)), p += strlen (p); - if ((MSymbol) mface_get_prop (face, Mvideomode) == Mreverse) - strcat (p, ",rev"), p += strlen (p); - if (mface_get_prop (face, Mhline)) - strcat (p, ",ul"), p += strlen (p); - if (mface_get_prop (face, Mbox)) - strcat (p, ",box"), p += strlen (p); - m17n_object_unref (face); - - XtSetArg (arg[0], XtNborderWidth, 1); - XtSetArg (arg[1], XtNlabel, buf); - XtSetValues (CurFaceWidget, arg, 2); - } - - if (control.cursor_pos < nchars) - { - MSymbol sym = Mnil; - - if (control.cursor_pos > 0 - && mtext_ref_char (mt, control.cursor_pos - 1) != '\n') - sym = mtext_get_prop (mt, control.cursor_pos - 1, Mlanguage); - if (sym == Mnil) - sym = mtext_get_prop (mt, control.cursor_pos, Mlanguage); - - if (sym == Mnil) - { - XtSetArg (arg[0], XtNborderWidth, 0); - XtSetArg (arg[1], XtNlabel, ""); - } - else - { - XtSetArg (arg[0], XtNborderWidth, 1); - XtSetArg (arg[1], XtNlabel, - msymbol_name (msymbol_get (sym, Mlanguage))); - XtSetValues (CurLangWidget, arg, 2); - } - XtSetValues (CurLangWidget, arg, 2); - - if (auto_input_method) - { - if (sym == Mnil) - select_input_method (-1); - else - { - int i; - - for (i = 0; i < num_input_methods; i++) - if (input_method_table[i]->language == sym) - break; - if (i < num_input_methods) - select_input_method (i); - else - select_input_method (-1); - } - } - } - - MenuHelpProc (MessageWidget, NULL, NULL, NULL); - - return True; -} - - -/* Hide the cursor. */ -void -hide_cursor () -{ - control.with_cursor = 0; - redraw_cursor (1); - XtAppAddWorkProc (context, show_cursor, NULL); -} - - -/* Update the window area between the Y-positions $Y0 and $OLD_Y1 to - $Y1 and $NEW_Y1 assuming that the text in the other area is not - changed. */ -void -update_region (int y0, int old_y1, int new_y1) -{ - if (y0 < 0) - y0 = 0; - if (new_y1 < old_y1) - { - if (old_y1 < win_height) - { - COPY_AREA (old_y1, win_height, new_y1); - redraw (win_height - (old_y1 - new_y1), win_height, 1, 0); - } - else - redraw (new_y1, win_height, 1, 0); - } - else if (new_y1 > old_y1) - { - if (new_y1 < win_height) - COPY_AREA (old_y1, win_height, new_y1); - } - if (new_y1 > win_height) - new_y1 = win_height; - redraw (y0, new_y1, 1, 1); -} - - -/* Delete the next $N characters. If $N is negative delete the - precious (- $N) characters. */ -void -delete_char (int n) -{ - MDrawMetric rect; - MDrawGlyphInfo info; - int old_y1, new_y1; - int from, to; - - if (n > 0) - from = cursor.from, to = from + n; - else - { - if (cursor.from == cur.from) - { - /* We are at the beginning of line. */ - int pos = cursor.prev_from; - - if (cursor.from == top.from) - { - /* We are at the beginning of screen. We must scroll - down. */ - GLYPH_INFO (bol (top.from - 1, 0), top.from - 1, info); - reseat (info.line_from); - } - update_cursor (pos, 1); - from = cursor.from; - to = cursor.to; - } - else - { - from = cursor.from - 1; - to = cursor.from; - } - } - - TEXT_EXTENTS (cur.from, bol (to + 1, 1), rect); - old_y1 = cur.y0 + rect.height; - - /* Now delete a character. */ - mtext_del (mt, from, to); - nchars--; - if (from >= top.from && from < top.to) - update_top (top.from); - update_cursor (from, 1); - - TEXT_EXTENTS (cur.from, bol (to, 1), rect); - new_y1 = cur.y0 + rect.height; - - update_region (cur.y0, old_y1, new_y1); -} - - -/* Insert M-text $NEWTEXT at the current cursor position. */ -void -insert_chars (MText *newtext) -{ - int n = mtext_len (newtext); - MDrawMetric rect; - int y0, old_y1, new_y1; - - if (SELECTEDP ()) - { - int n = (mtext_property_end (selection) - - mtext_property_start (selection)); - mtext_detach_property (selection); - delete_char (n); - } - - y0 = cur.y0; - TEXT_EXTENTS (cur.from, bol (cur.to - 1, 1), rect); - old_y1 = y0 + rect.height; - - /* Now insert chars. */ - mtext_ins (mt, cursor.from, newtext); - nchars += n; - if (cur.from == top.from) - update_top (top.from); - update_cursor (cursor.from + n, 1); - - TEXT_EXTENTS (cur.from, bol (cur.to - 1, 1), rect); - new_y1 = cur.y0 + rect.height; - - update_region (y0, old_y1, new_y1); - update_selection (); -} - - -/* Convert the currently selected text to COMPOUND-TEXT. It is called - when someone requests the current value of the selection. */ -Boolean -covert_selection (Widget w, Atom *selection_atom, - Atom *target, Atom *return_type, - XtPointer *value, unsigned long *length, int *format) -{ - unsigned char *buf = (unsigned char *) XtMalloc (4096); - MText *this_mt = mtext (); - int from = mtext_property_start (selection); - int to = mtext_property_end (selection); - - mtext_copy (this_mt, 0, mt, from, to); - *length = mconv_encode_buffer (msymbol ("compound-text"), - this_mt, buf, 4096); - *return_type = XA_COMPOUND_TEXT; - *value = (XtPointer) buf; - *format = 8; - m17n_object_unref (this_mt); - return True; -} - - -/* Unselect the text. It is called when we loose the selection. */ -void -lose_selection (Widget w, Atom *selection_atom) -{ - if (SELECTEDP ()) - { - mtext_detach_property (selection); - redraw (sel_start.y0, sel_end.y1, 1, 0); - } -} - -void -get_selection (Widget w, XtPointer cliend_data, Atom *selection, Atom *type, - XtPointer value, unsigned long *length, int *format) -{ - MText *this_mt; - MSymbol coding; - - if (*type == XT_CONVERT_FAIL || ! value) - goto err; - if (*type == XA_STRING) - coding = Mnil; - else if (*type == XA_COMPOUND_TEXT) - coding = msymbol ("compound-text"); - else if (*type == XA_UTF8_STRING) - coding = msymbol ("utf-8"); - else - goto err; - - this_mt = mconv_decode_buffer (coding, (unsigned char *) value, *length); - if (this_mt) - { - hide_cursor (); - insert_chars (this_mt); - m17n_object_unref (this_mt); - } - - err: - if (value) - XtFree (value); -} - -static void -ExposeProc (Widget w, XEvent *event, String *str, Cardinal *num) -{ - XExposeEvent *expose = (XExposeEvent *) event; - - if (top.from < 0) - { - Dimension width_max, width; - - XtSetArg (arg[0], XtNwidth, &width); - XtGetValues (XtParent (w), arg, 1); - width_max = width; - XtGetValues (HeadWidget, arg, 1); - if (width_max < width) - width_max = width; - XtGetValues (FaceWidget, arg, 1); - if (width_max < width) - width_max = width; - XtGetValues (LangWidget, arg, 1); - if (width_max < width) - width_max = width; - XtSetArg (arg[0], XtNwidth, width_max); - XtSetValues (HeadWidget, arg, 1); - XtSetValues (FaceWidget, arg, 1); - XtSetValues (LangWidget, arg, 1); - XtSetValues (XtParent (w), arg, 1); - XtSetValues (TailWidget, arg, 1); - - update_top (0); - update_cursor (0, 1); - redraw (0, win_height, 0, 1); - show_cursor (NULL); - } - else - { - redraw (expose->y, expose->y + expose->height, 0, 0); - if (current_input_context - && expose->y < cur.y0 && expose->y + expose->height < cur.y1) - set_input_method_spot (); - } -} - -static void -ConfigureProc (Widget w, XEvent *event, String *str, Cardinal *num) -{ - XConfigureEvent *configure = (XConfigureEvent *) event; - - hide_cursor (); - control.max_line_width = win_width = configure->width; - win_height = configure->height; - mdraw_clear_cache (mt); - update_top (0); - update_cursor (0, 1); - redraw (0, win_height, 1, 1); - if (current_input_context) - set_input_method_spot (); -} - -static void -ButtonProc (Widget w, XEvent *event, String *str, Cardinal *num) -{ - int pos; - int x = event->xbutton.x; - int y = event->xbutton.y - top.ascent; - - if (control.orientation_reversed) - x -= win_width; - pos = COORDINATES_POSITION (top.from, nchars + 1, x, y); - if (SELECTEDP ()) - { - XtDisownSelection (w, XA_PRIMARY, CurrentTime); - mtext_detach_property (selection); - redraw (sel_start.y0, sel_end.y1, 1, 0); - } - hide_cursor (); - update_cursor (pos, 0); -} - - -static void -ButtonReleaseProc (Widget w, XEvent *event, String *str, Cardinal *num) -{ - if (! SELECTEDP ()) - return; - - XtOwnSelection (w, XA_PRIMARY, CurrentTime, - covert_selection, lose_selection, NULL); - update_cursor (mtext_property_start (selection), 0); -} - -static -void -Button2Proc (Widget w, XEvent *event, String *str, Cardinal *num) -{ - if (! SELECTEDP ()) - { - /* We don't have a local selection. */ - XtGetSelectionValue (w, XA_PRIMARY, XA_TEXT, get_selection, NULL, - CurrentTime); - } - else - { - int from = mtext_property_start (selection); - int to = mtext_property_end (selection); - MText *this_mt; - int pos; - int x = event->xbutton.x; - int y = event->xbutton.y - top.ascent; - - if (control.orientation_reversed) - x -= win_width; - pos = COORDINATES_POSITION (top.from, nchars + 1, x, y); - - XtDisownSelection (w, XA_PRIMARY, CurrentTime); - mtext_detach_property (selection); - hide_cursor (); - this_mt = mtext_copy (mtext (), 0, mt, from, to); - update_cursor (pos, 0); - insert_chars (this_mt); - m17n_object_unref (this_mt); - } -} - -static void -ButtonMoveProc (Widget w, XEvent *event, String *str, Cardinal *num) -{ - int pos; - int x = event->xbutton.x; - int y = event->xbutton.y; - - if (control.orientation_reversed) - x -= win_width; - if (y < cur.y0) - pos = top.from, y -= top.ascent; - else - pos = cur.from, y -= cur.y0 + cur.ascent; - pos = COORDINATES_POSITION (pos, nchars + 1, x, y); - - if (pos == cursor.from) - return; - - hide_cursor (); - if (SELECTEDP ()) - { - /* Selection range changed. */ - int from = mtext_property_start (selection); - int to = mtext_property_end (selection); - int start_y0 = sel_start.y0, start_y1 = sel_start.y1; - int end_y0 = sel_end.y0, end_y1 = sel_end.y1; - - if (cursor.from == from) - { - /* Start position of selection changed. */ - select_region (pos, to); - if (pos > from) - /* Shrunken. Previous selection face must be cleared. */ - redraw (start_y0, sel_start.y1, 1, 0); - else - /* Enlarged. We can simply overdraw. */ - redraw (sel_start.y0, start_y1, 0, 0); - } - else - { - /* End position of selection changed. */ - select_region (from, pos); - if (pos < to) - /* Shrunken. Previous selection face must be cleared. */ - redraw (sel_end.y0, end_y1, 1, 0); - else - /* Enlarged. We can simply overdraw. */ - redraw (end_y0, sel_end.y1, 0, 0); - } - } - else - { - /* Newly selected. */ - select_region (pos, cursor.from); - redraw (sel_start.y0, sel_end.y1, 0, 0); - } - update_cursor (pos, 1); -} - -void -ScrollProc (Widget w, XtPointer client_data, XtPointer position) -{ - int from; - MDrawGlyphInfo info; - int height; - int cursor_pos = cursor.from; - - if (((int) position) < 0) - { - /* Scroll down. */ - int pos; - - from = top.from; - height = top.y1 - top.y0; - while (from > 0) - { - pos = bol (from - 1, 0); - GLYPH_INFO (pos, from - 1, info); - if (height + info.this.height > win_height) - break; - height += info.this.height; - from = info.line_from; - } - if (cursor_pos >= top.to) - { - cursor_pos = top.from; - pos = top.to; - while (cursor_pos < nchars) - { - GLYPH_INFO (pos, pos, info); - if (height + info.this.height > win_height) - break; - height += info.this.height; - cursor_pos = pos; - pos = info.line_to; - } - } - } - else if (cur.to < nchars) - { - /* Scroll up, but leave at least one line. */ - from = cur.to; - height = cur.y1; - while (from < nchars) - { - GLYPH_INFO (from, from, info); - if (height + info.this.height > win_height - || info.line_to >= nchars) - break; - height += info.this.height; - from = info.line_to; - } - if (from == nchars) - from = info.line_from; - if (cursor_pos < from) - cursor_pos = from; - } - else - /* Scroll up to make the cursor line top. */ - from = cur.from; - hide_cursor (); - reseat (from); - update_cursor (cursor_pos, 1); -} - -void -JumpProc (Widget w, XtPointer client_data, XtPointer persent_ptr) -{ - float persent = *(float *) persent_ptr; - int pos1, pos2 = nchars * persent; - MDrawGlyphInfo info; - - hide_cursor (); - pos1 = bol (pos2, 0); - GLYPH_INFO (pos1, pos2, info); - pos1 = info.line_from; - reseat (pos1); - update_cursor (pos1, 1); -} - - -static void -KeyProc (Widget w, XEvent *event, String *str, Cardinal *num) -{ - XKeyEvent *key_event = (XKeyEvent *) event; - char buf[512]; - KeySym keysym = NoSymbol; - int ret; - /* If set to 1, do not update target_x_position. */ - int keep_target_x_position = 0; - MText *produced; - - if (current_input_context - && minput_filter (current_input_context, Mnil, event)) - return; - if (event->type == KeyRelease) - return; - - hide_cursor (); - - produced = mtext (); - ret = minput_lookup (current_input_context, Mnil, event, produced); - if (mtext_len (produced) > 0) - insert_chars (produced); - if (ret) - ret = XLookupString (key_event, buf, sizeof (buf), &keysym, NULL); - m17n_object_unref (produced); - - switch (keysym) - { - case XK_Delete: - { - int n = 0; - - if (SELECTEDP ()) - { - n = (mtext_property_end (selection) - - mtext_property_start (selection)); - mtext_detach_property (selection); - } - else if (cursor.from < nchars) - { - /* Delete the following grapheme cluster. */ - n = cursor.to - cursor.from; - } - if (n != 0) - delete_char (n); - } - break; - - case XK_BackSpace: - { - int n = 0; - - if (SELECTEDP ()) - { - /* Delete selected region. */ - n = (mtext_property_end (selection) - - mtext_property_start (selection)); - mtext_detach_property (selection); - } - else if (cursor.from > 0) - { - /* Delete the preceding character. */ - n = -1; - } - if (n != 0) - delete_char (n); - } - break; - - case XK_Left: - if (SELECTEDP ()) - { - mtext_detach_property (selection); - redraw (sel_start.y0, sel_end.y1, 1, 0);; - } - if (logical_move) - { - if (cursor.prev_from >= 0) - update_cursor (cursor.prev_from, 0); - } - else - { - if (cursor.left_from >= 0) - update_cursor (cursor.left_from, 0); - } - break; - - case XK_Right: - if (SELECTEDP ()) - { - mtext_detach_property (selection); - redraw (sel_start.y0, sel_end.y1, 1, 0);; - } - if (logical_move) - { - if (cursor.next_to >= 0) - update_cursor (cursor.to, 0); - } - else - { - if (cursor.right_from >= 0) - update_cursor (cursor.right_from, 0); - } - break; - - case XK_Down: - if (SELECTEDP ()) - { - mtext_detach_property (selection); - redraw (sel_start.y0, sel_end.y1, 1, 0);; - } - if (cur.to <= nchars) - { - MDrawGlyphInfo info; - int pos; - - GLYPH_INFO (cur.from, cur.to, info); - pos = COORDINATES_POSITION (cur.from, nchars + 1, - target_x_position, info.y); - keep_target_x_position = 1; - update_cursor (pos, 0); - } - break; - - case XK_Up: - if (SELECTEDP ()) - { - mtext_detach_property (selection); - redraw (sel_start.y0, sel_end.y1, 1, 0);; - } - if (cur.from > 0) - { - MDrawMetric rect; - int y; - int pos = bol (cur.from - 1, 0); - - TEXT_EXTENTS (pos, cur.from - 1, rect); - y = rect.height + rect.y - 1; - pos = COORDINATES_POSITION (pos, nchars, - target_x_position, y); - keep_target_x_position = 1; - update_cursor (pos, 0); - } - break; - - case XK_Page_Down: - if (SELECTEDP ()) - { - mtext_detach_property (selection); - redraw (sel_start.y0, sel_end.y1, 1, 0);; - } - if (top.from < nchars) - ScrollProc (w, NULL, (XtPointer) 1); - break; - - case XK_Page_Up: - if (SELECTEDP ()) - { - mtext_detach_property (selection); - redraw (sel_start.y0, sel_end.y1, 1, 0);; - } - if (top.from > 0) - ScrollProc (w, NULL, (XtPointer) -1); - break; - - default: - if (ret > 0) - { - if (buf[0] == 17) /* C-q */ - { - XtAppSetExitFlag (context); - return; - } - else if (buf[0] == 12) /* C-l */ - { - redraw (0, win_height, 1, 1); - return; - } - else - { - MText *temp = mtext (); - - mtext_cat_char (temp, buf[0] == '\r' ? '\n' : buf[0]); - if (current_input_context) - mtext_put_prop (temp, 0, 1, Mlanguage, - current_input_context->im->language); - insert_chars (temp); - m17n_object_unref (temp); - } - } - } - - if (! keep_target_x_position) - target_x_position = cursor.x; -} - -void -SaveProc (Widget w, XtPointer client_data, XtPointer call_data) -{ - char *name = (char *) client_data; - FILE *fp; - int from = -1, to = 0; - - if (name) - { - free (filename); - filename = strdup (name); - } - - fp = fopen (filename, "w"); - if (! fp) - { - fprintf (stderr, "Open for write fail: %s", filename); - return; - } - - if (SELECTEDP ()) - { - from = mtext_property_start (selection); - to = mtext_property_end (selection); - mtext_detach_property (selection); - } - - mconv_encode_stream (Mcoding_utf_8, mt, fp); - fclose (fp); - if (from >= 0) - select_region (from, to); -} - -void -SerializeProc (Widget w, XtPointer client_data, XtPointer call_data) -{ - MText *new; - - hide_cursor (); - if (SELECTEDP ()) - mtext_detach_property (selection); - serialized = (int) client_data; - if (! serialized) - new = mtext_deserialize (mt); - else - { - MPlist *plist = mplist (); - - mplist_push (plist, Mt, Mface); - mplist_push (plist, Mt, Mlanguage); - new = mtext_serialize (mt, 0, mtext_len (mt), plist); - m17n_object_unref (plist); - } - if (new) - { - m17n_object_unref (mt); - mt = new; - serialized = ! serialized; - nchars = mtext_len (mt); - update_top (0); - } - update_cursor (0, 1); - redraw (0, win_height, 1, 1); -} - -void -QuitProc (Widget w, XtPointer client_data, XtPointer call_data) -{ - XtAppSetExitFlag (context); -} - -MText * -read_file () -{ - FILE *fp = fopen (filename, "r"); - - if (! fp) - FATAL_ERROR ("Can't read \"%s\"!\n", filename); - mt = mconv_decode_stream (Mcoding_utf_8, fp); - fclose (fp); - if (! mt) - FATAL_ERROR ("Can't decode \"%s\" by UTF-8!\n", filename); - return mt; -} - -void -BidiProc (Widget w, XtPointer client_data, XtPointer call_data) -{ - int data = (int) client_data; - int i; - - if (data == 0) - { - control.enable_bidi = 0; - control.orientation_reversed = 0; - } - else - { - control.enable_bidi = 1; - control.orientation_reversed = data == 2; - } - for (i = 0; i < 3; i++) - { - if (i == data) - XtSetArg (arg[0], XtNleftBitmap, CheckPixmap); - else - XtSetArg (arg[0], XtNleftBitmap, None); - XtSetValues (BidiMenus[i], arg, 1); - } - - update_cursor (cursor.from, 1); - redraw (0, win_height, 1, 0); -} - -extern int line_break (MText *mt, int pos, int from, int to, int line, int y); - -void -LineBreakProc (Widget w, XtPointer client_data, XtPointer call_data) -{ - int data = (int) client_data; - int i; - - if (data == 0) - control.max_line_width = 0; - else - { - control.max_line_width = win_width; - control.line_break = (data == 1 ? NULL : line_break); - } - for (i = 0; i < 3; i++) - { - if (i == data) - XtSetArg (arg[0], XtNleftBitmap, CheckPixmap); - else - XtSetArg (arg[0], XtNleftBitmap, None); - XtSetValues (LineBreakMenus[i], arg, 1); - } - - update_cursor (cursor.from, 1); - redraw (0, win_height, 1, 0); -} - -void -CursorProc (Widget w, XtPointer client_data, XtPointer call_data) -{ - int data = (int) client_data; - int i, from, to; - - switch (data) - { - case 0: - logical_move = 1; - from = 0, to = 2; - break; - case 1: - logical_move = 0; - from = 0, to = 2; - break; - case 2: - control.cursor_bidi = 0, control.cursor_width = -1; - from = 2, to = 5; - break; - case 3: - control.cursor_bidi = 0, control.cursor_width = 2; - from = 2, to = 5; - break; - default: - control.cursor_bidi = 1; - from = 2, to = 5; - break; - } - - for (i = from; i < to; i++) - { - if (i == data) - XtSetArg (arg[0], XtNleftBitmap, CheckPixmap); - else - XtSetArg (arg[0], XtNleftBitmap, None); - XtSetValues (CursorMenus[i], arg, 1); - } - - redraw (0, win_height, 1, 0); -} - -static void -InputMethodProc (Widget w, XtPointer client_data, XtPointer call_data) -{ - int idx = (int) client_data; - - if (idx == -2 ? current_input_method < 0 - : idx == -1 ? auto_input_method - : idx == current_input_method) - return; - - XtSetArg (arg[0], XtNleftBitmap, None); - if (auto_input_method) - { - XtSetValues (InputMethodMenus[1], arg, 1); - auto_input_method = 0; - } - else if (current_input_method < 0) - XtSetValues (InputMethodMenus[0], arg, 1); - else - XtSetValues (InputMethodMenus[current_input_method + 2], arg, 1); - - if (idx == -1) - { - auto_input_method = 1; - hide_cursor (); - } - else - select_input_method (idx); - XtSetArg (arg[0], XtNleftBitmap, CheckPixmap); - XtSetValues (InputMethodMenus[idx + 2], arg, 1); -} - -void -FaceProc (Widget w, XtPointer client_data, XtPointer call_data) -{ - int idx = (int) client_data; - int from, to; - int old_y1; - - if (! SELECTEDP ()) - return; - - XtAppAddWorkProc (context, show_cursor, NULL); - from = mtext_property_start (selection); - to = mtext_property_end (selection); - old_y1 = sel_end.y1; - - mtext_detach_property (selection); - if (idx >= 0) - { - MTextProperty *prop = mtext_property (Mface, *face_table[idx].face, - MTEXTPROP_REAR_STICKY); - mtext_push_property (mt, from, to, prop); - m17n_object_unref (prop); - } - else - mtext_pop_prop (mt, from, to, Mface); - if (from < top.to) - update_top (top.from); - update_cursor (cursor.from, 1); - select_region (from, to); - update_region (sel_start.y0, old_y1, sel_end.y1); - if (cur.y1 > win_height) - { - while (cur.y1 > win_height) - { - reseat (top.to); - update_cursor (cursor.from, 1); - } - } -} - -void -LangProc (Widget w, XtPointer client_data, XtPointer call_data) -{ - MSymbol sym = (MSymbol) client_data; - int from, to; - int old_y1; - - if (! SELECTEDP ()) - return; - - XtAppAddWorkProc (context, show_cursor, NULL); - from = mtext_property_start (selection); - to = mtext_property_end (selection); - old_y1 = sel_end.y1; - - mtext_detach_property (selection); - if (sym != Mnil) - mtext_put_prop (mt, from, to, Mlanguage, sym); - else - mtext_pop_prop (mt, from, to, Mlanguage); - - if (from < top.to) - update_top (top.from); - update_cursor (cursor.from, 1); - select_region (from, to); - update_region (sel_start.y0, old_y1, sel_end.y1); - if (cur.y1 > win_height) - { - while (cur.y1 > win_height) - { - reseat (top.to); - update_cursor (cursor.from, 1); - } - } -} - -void -DumpImageProc (Widget w, XtPointer client_data, XtPointer call_data) -{ - int narrowed = (int) client_data; - FILE *mdump; - int from, to; - MConverter *converter; - - if (narrowed) - { - if (! SELECTEDP ()) - return; - from = mtext_property_start (selection); - to = mtext_property_end (selection); - } - else - { - from = 0; - to = nchars; - } - - if (! narrowed) - mdump = popen ("mdump -q -p a4", "w"); - else - mdump = popen ("mdump -q", "w"); - if (! mdump) - return; - converter = mconv_stream_converter (Mcoding_utf_8, mdump); - mconv_encode_range (converter, mt, from, to); - mconv_free_converter (converter); - fclose (mdump); -} - -void -input_status (MInputContext *ic, MSymbol command) -{ - XFillRectangle (display, input_status_pixmap, gc_inv, - 0, 0, input_status_width, input_status_height); - if (command == Minput_status_draw) - { - MDrawMetric rect; - - mtext_put_prop (ic->status, 0, mtext_len (ic->status), - Mface, face_input_status); - if (ic->im->language != Mnil) - mtext_put_prop (ic->status, 0, mtext_len (ic->status), - Mlanguage, ic->im->language); - mdraw_text_extents (frame, ic->status, 0, mtext_len (ic->status), - NULL, NULL, NULL, &rect); - mdraw_text (frame, (MDrawWindow) input_status_pixmap, - input_status_width - rect.width - 2, - rect.y, - ic->status, 0, mtext_len (ic->status)); - } - XtSetArg (arg[0], XtNbitmap, input_status_pixmap); - XtSetValues (CurIMStatus, arg, 1); -} - -int -compare_input_method (const void *elt1, const void *elt2) -{ - const MInputMethod *im1 = *(MInputMethod **) elt1; - const MInputMethod *im2 = *(MInputMethod **) elt2; - MSymbol lang1, lang2; - - if (im1->language == Mnil) - return 1; - if (im1->language == im2->language) - return strcmp (msymbol_name (im1->name), msymbol_name (im2->name)); - if (im1->language == Mt) - return 1; - if (im2->language == Mt) - return -1; - lang1 = msymbol_get (im1->language, Mlanguage); - lang2 = msymbol_get (im2->language, Mlanguage); - return strcmp (msymbol_name (lang1), msymbol_name (lang2)); -} - -void -setup_input_methods (int with_xim) -{ - MInputMethod *im = NULL; - MInputXIMArgIM arg_xim; - MPlist *plist = mdatabase_list (msymbol ("input-method"), Mnil, Mnil, Mnil); - MPlist *pl; - int i = 0; - - num_input_methods = mplist_length (plist); - - if (with_xim) - { - arg_xim.display = display; - arg_xim.db = NULL; - arg_xim.res_name = arg_xim.res_class = NULL; - arg_xim.locale = NULL; - arg_xim.modifier_list = NULL; - im = minput_open_im (Mnil, msymbol ("xim"), &arg_xim); - if (im) - num_input_methods++; - } - input_method_table = calloc (num_input_methods, sizeof (MInputMethod *)); - if (im) - input_method_table[i++] = im; - for (pl = plist; mplist_key (pl) != Mnil; pl = mplist_next (pl)) - { - MDatabase *mdb = mplist_value (pl); - MSymbol *tag = mdatabase_tag (mdb); - - if (tag[1] != Mnil) - { - im = minput_open_im (tag[1], tag[2], NULL); - if (im) - input_method_table[i++] = im; - } - } - - m17n_object_unref (plist); - num_input_methods = i; - qsort (input_method_table, num_input_methods, sizeof input_method_table[0], - compare_input_method); - current_input_context = NULL; - - mplist_put (minput_driver->callback_list, Minput_status_start, - (void *) input_status); - mplist_put (minput_driver->callback_list, Minput_status_draw, - (void *) input_status); - mplist_put (minput_driver->callback_list, Minput_status_done, - (void *) input_status); -} - - -static void -MenuHelpProc (Widget w, XEvent *event, String *str, Cardinal *num) -{ - char *msg; - - if (num && *num > 0) - { - int bytes = 0, i; - - for (i = 0; i < *num; i++) - bytes += strlen (str[i]) + 1; - msg = alloca (bytes); - strcpy (msg, str[0]); - for (i = 1; i < *num; i++) - strcat (msg, " "), strcat (msg, str[i]); - } - else if (cursor.from < nchars) - { - int c = mtext_ref_char (mt, cursor.from); - char *name = mchar_get_prop (c, Mname); - - if (! name) - name = ""; - msg = alloca (10 + strlen (name)); - sprintf (msg, "U+%04X %s", c, name); - } - else - { - msg = ""; - } - XtSetArg (arg[0], XtNlabel, msg); - XtSetValues (MessageWidget, arg, 1); -} - -typedef struct -{ - int type; - char *name1, *name2; - XtCallbackProc proc; - XtPointer client_data; - int status; - Widget w; -} MenuRec; - -void PopupProc (Widget w, XtPointer client_data, XtPointer call_data); - -void SaveProc (Widget w, XtPointer client_data, XtPointer call_data); - -MenuRec FileMenu[] = - { { 0, "Open", NULL, PopupProc, FileMenu + 0, -1 }, - { 0, "Save", NULL, SaveProc, NULL, -1 }, - { 0, "Save as", NULL, PopupProc, FileMenu + 2, -1 }, - { 1 }, - { 0, "Serialize", NULL, SerializeProc, (void *) 1, -1 }, - { 0, "Deserialize", NULL, SerializeProc, (void *) 0, -1 }, - { 1 }, - { 0, "Dump Image Buffer", NULL, DumpImageProc, (void *) 0, -1 }, - { 0, "Dump Image Region", NULL, DumpImageProc, (void *) 1, -1 }, - { 1 }, - { 0, "Quit", NULL, QuitProc, NULL, -1 } }; - -void -PopupProc (Widget w, XtPointer client_data, XtPointer call_data) -{ - MenuRec *rec = (MenuRec *) client_data; - Position x, y; - - XtSetArg (arg[0], XtNvalue, ""); - XtSetArg (arg[1], XtNlabel, rec->name1); - XtSetValues (FileDialogWidget, arg, 2); - XtTranslateCoords (w, (Position) 0, (Position) 0, &x, &y); - XtSetArg (arg[0], XtNx, x + 20); - XtSetArg (arg[1], XtNy, y + 10); - XtSetValues (FileShellWidget, arg, 2); - XtPopup (FileShellWidget, XtGrabExclusive); -} - -void -FileDialogProc (Widget w, XtPointer client_data, XtPointer call_data) -{ - FILE *fp; - char *label; - - XtPopdown (FileShellWidget); - if ((int) client_data == 1) - return; - XtSetArg (arg[0], XtNlabel, &label); - XtGetValues (FileDialogWidget, arg, 1); - if (strcmp (label, FileMenu[0].name1) == 0) - { - /* Open a file */ - free (filename); - filename = strdup ((char *) XawDialogGetValueString (FileDialogWidget)); - fp = fopen (filename, "r"); - hide_cursor (); - m17n_object_unref (mt); - if (fp) - { - mt = mconv_decode_stream (Mcoding_utf_8, fp); - fclose (fp); - if (! mt) - mt = mtext (); - } - else - mt = mtext (); - serialized = 0; - nchars = mtext_len (mt); - update_top (0); - update_cursor (0, 1); - redraw (0, win_height, 1, 1); - } - else if (strcmp (label, FileMenu[2].name1) == 0) - SaveProc (w, (XtPointer) XawDialogGetValueString (FileDialogWidget), NULL); - else - fprintf (stderr, "Invalid calling sequence: FileDialogProc\n"); -} - -#define SetMenu(MENU, TYPE, NAME1, NAME2, PROC, DATA, STATUS) \ - ((MENU).type = (TYPE), (MENU).name1 = (NAME1), (MENU).name2 = (NAME2), \ - (MENU).proc = (PROC), (MENU).client_data = (XtPointer) (DATA), \ - (MENU).status = (STATUS)) - - -Widget -create_menu_button (Widget top, Widget parent, Widget left, char *button_name, - char *menu_name, MenuRec *menus, int num_menus, char *help) -{ - Widget button, menu; - char *fmt = ": highlight() MenuHelp(%s)\n\ - : reset() MenuHelp()\n\ - : reset() PopupMenu()\n\ - : highlight()"; - int i; - MenuRec *m; - char *trans; - int max_width = 0; - - menu = XtCreatePopupShell (menu_name, simpleMenuWidgetClass, top, NULL, 0); - for (i = 0; i < num_menus; i++) - { - m = menus + i; - if (m->type == 0) - { - if (m->proc) - { - int n = 0; - - if (m->status >= 0) - { - XtSetArg (arg[n], XtNleftMargin, 20), n++; - if (m->status > 0) - XtSetArg (arg[n], XtNleftBitmap, CheckPixmap), n++; - } - m->w = XtCreateManagedWidget (m->name1, smeBSBObjectClass, - menu, arg, n); - XtAddCallback (m->w, XtNcallback, m->proc, m->client_data); - } - else - { - XtSetArg (arg[0], XtNsensitive, False); - m->w = XtCreateManagedWidget (m->name1, smeBSBObjectClass, - menu, arg, 2); - } - } - else - { - XtCreateManagedWidget (m->name1, smeLineObjectClass, menu, NULL, 0); - } - if (m->name2) - max_width = 1; - } - trans = alloca (strlen (fmt) + strlen (help)); - sprintf (trans, fmt, help); - XtSetArg (arg[0], XtNmenuName, menu_name); - XtSetArg (arg[1], XtNtranslations, XtParseTranslationTable ((String) trans)); - XtSetArg (arg[2], XtNinternalWidth, 2); - XtSetArg (arg[3], XtNhighlightThickness, 1); - XtSetArg (arg[4], XtNleft, XawChainLeft); - XtSetArg (arg[5], XtNright, XawChainLeft); - i = 6; - if (left) - XtSetArg (arg[i], XtNfromHoriz, left), i++; - button = XtCreateManagedWidget (button_name, menuButtonWidgetClass, parent, - arg, i); - - if (max_width) - { - int height, ascent, *width = alloca (sizeof (int) * num_menus); - int *len = alloca (sizeof (int) * num_menus); - - XFontSet font_set; - XFontSetExtents *fontset_extents; - - XtSetArg (arg[0], XtNfontSet, &font_set); - XtGetValues (button, arg, 1); - - fontset_extents = XExtentsOfFontSet (font_set); - height = fontset_extents->max_logical_extent.height; - ascent = - fontset_extents->max_logical_extent.y; - - for (i = 0; i < num_menus; i++) - if (menus[i].name2) - { - len[i] = strlen (menus[i].name2); - width[i] = XmbTextEscapement (font_set, menus[i].name2, len[i]); - if (max_width < width[i]) - max_width = width[i]; - } - for (i = 0; i < num_menus; i++) - if (menus[i].name2) - { - Pixmap pixmap = XCreatePixmap (display, - RootWindow (display, screen), - max_width, height, 1); - XFillRectangle (display, pixmap, mono_gc_inv, - 0, 0, max_width, height); - XmbDrawString (display, pixmap, font_set, mono_gc, - max_width - width[i], ascent, - menus[i].name2, len[i]); - XtSetArg (arg[0], XtNrightBitmap, pixmap); - XtSetArg (arg[1], XtNrightMargin, max_width + 20); - XtSetValues (menus[i].w, arg, 2); - } - } - - return button; -} - - -XtActionsRec actions[] = { - {"Expose", ExposeProc}, - {"Configure", ConfigureProc}, - {"Key", KeyProc}, - {"ButtonPress", ButtonProc}, - {"ButtonRelease", ButtonReleaseProc}, - {"ButtonMotion", ButtonMoveProc}, - {"Button2Press", Button2Proc}, - {"MenuHelp", MenuHelpProc} -}; - - -/* Print the usage of this program (the name is PROG), and exit with - EXIT_CODE. */ - -void -help_exit (char *prog, int exit_code) -{ - char *p = prog; - - while (*p) - if (*p++ == '/') - prog = p; - - printf ("Usage: %s [ XT-OPTION ...] [ OPTION ...] FILE\n", prog); - printf ("Display FILE on a window and allow users to edit it.\n"); - printf ("XT-OPTIONs are standard Xt arguments (e.g. -fn, -fg).\n"); - printf ("The following OPTIONs are available.\n"); - printf (" %-13s %s", "--version", "print version number\n"); - printf (" %-13s %s", "-h, --help", "print this message\n"); - exit (exit_code); -} - -int -main (int argc, char **argv) -{ - Widget form, BodyWidget, w; - char *fontset_name = NULL; - int col = 80, row = 32; - /* Translation table for TextWidget. */ - String trans = ": Expose()\n\ - : Configure()\n\ - : Key()\n\ - : Key()\n\ - : ButtonPress()\n\ - : ButtonRelease()\n\ - : ButtonMotion()\n\ - : Button2Press()"; - /* Translation table for the top form widget. */ - String trans2 = ": Key()\n\ - : Key()"; - String pop_face_trans - = ": MenuHelp(Pop face property) highlight()\n\ - : MenuHelp() reset()\n\ - : set()\n\ - : notify() unset()"; - String pop_lang_trans - = ": MenuHelp(Pop language property) highlight()\n\ - : MenuHelp() reset()\n\ - : set()\n\ - : notify() unset()"; - int font_width, font_ascent, font_descent; - int with_xim = 0; - int i, j; - - setlocale (LC_ALL, ""); - /* Create the top shell. */ - XtSetLanguageProc (NULL, NULL, NULL); - ShellWidget = XtOpenApplication (&context, "MEdit", NULL, 0, &argc, argv, - NULL, sessionShellWidgetClass, NULL, 0); - display = XtDisplay (ShellWidget); - screen = XScreenNumberOfScreen (XtScreen (ShellWidget)); - - /* Parse the remaining command line arguments. */ - for (i = 1; i < argc; i++) - { - if (! strcmp (argv[i], "--help") - || ! strcmp (argv[i], "-h")) - help_exit (argv[0], 0); - else if (! strcmp (argv[i], "--version")) - { - printf ("medit (m17n library) %s\n", VERSION); - printf ("Copyright (C) 2003 AIST, JAPAN\n"); - exit (0); - } - else if (! strcmp (argv[i], "--geometry")) - { - i++; - if (sscanf (argv[i], "%dx%d", &col, &row) != 2) - help_exit (argv[0], 1); - } - else if (! strcmp (argv[i], "--fontset")) - { - i++; - fontset_name = strdup (argv[i]); - } - else if (! strcmp (argv[i], "--with-xim")) - { - with_xim = 1; - } - else if (argv[i][0] != '-') - { - filename = strdup (argv[i]); - } - else - { - fprintf (stderr, "Unknown option: %s", argv[i]); - help_exit (argv[0], 1); - } - } - if (! filename) - help_exit (argv[0], 1); - - mdatabase_dir = "."; - /* Initialize the m17n library. */ - M17N_INIT (); - if (merror_code != MERROR_NONE) - FATAL_ERROR ("%s\n", "Fail to initialize the m17n library!"); - - mt = read_file (filename); - serialized = 0; - - nchars = mtext_len (mt); - - { - MFace *face = mface (); - - mface_put_prop (face, Mbackground, msymbol ("blue")); - mface_put_prop (face, Mforeground, msymbol ("yellow")); - selection = mtext_property (Mface, face, MTEXTPROP_NO_MERGE); - m17n_object_unref (face); - } - - /* This tells ExposeProc to initialize everything. */ - top.from = -1; - - XA_TEXT = XInternAtom (display, "TEXT", False); - XA_COMPOUND_TEXT = XInternAtom (display, "COMPOUND_TEXT", False); - XA_UTF8_STRING = XInternAtom (display, "UTF8_STRING", False); - { - MPlist *plist = mplist (); - MFace *face; - MFont *font; - - mplist_put (plist, msymbol ("widget"), ShellWidget); - if (fontset_name) - { - MFontset *fontset = mfontset (fontset_name); - - face = mface (); - mface_put_prop (face, Mfontset, fontset); - m17n_object_unref (fontset); - mplist_add (plist, Mface, face); - m17n_object_unref (face); - } - frame = mframe (plist); - m17n_object_unref (plist); - face_default = (MFace *) mframe_get_prop (frame, Mface); - face_default_fontset = mface (); - mface_put_prop (face_default_fontset, Mfontset, - mface_get_prop (face_default, Mfontset)); - - font = (MFont *) mframe_get_prop (frame, Mfont); - default_font_size = (int) mfont_get_prop (font, Msize); - } - - font_width = (int) mframe_get_prop (frame, Mfont_width); - font_ascent = (int) mframe_get_prop (frame, Mfont_ascent); - font_descent = (int) mframe_get_prop (frame, Mfont_descent); - win_width = font_width * col; - win_height = (font_ascent + font_descent) * row; - - { - MFaceBoxProp prop; - - prop.width = 4; - prop.color_top = prop.color_left = msymbol ("magenta"); - prop.color_bottom = prop.color_right = msymbol ("red"); - prop.inner_hmargin = prop.inner_vmargin = 1; - prop.outer_hmargin = prop.outer_vmargin = 2; - - face_box = mface (); - mface_put_prop (face_box, Mbox, &prop); - } - - face_courier = mface (); - mface_put_prop (face_courier, Mfamily, msymbol ("courier")); - face_helvetica = mface (); - mface_put_prop (face_helvetica, Mfamily, msymbol ("helvetica")); - face_times = mface (); - mface_put_prop (face_times, Mfamily, msymbol ("times")); - face_dv_ttyogesh = mface (); - mface_put_prop (face_dv_ttyogesh, Mfamily, msymbol ("dv-ttyogesh")); - face_freesans = mface (); - mface_put_prop (face_freesans, Mfamily, msymbol ("freesans")); - face_freemono = mface (); - mface_put_prop (face_freemono, Mfamily, msymbol ("freemono")); - - face_xxx_large = mface (); - mface_put_prop (face_xxx_large, Mratio, (void *) 300); - { - MFont *latin_font = mframe_get_prop (frame, Mfont); - MFont *dev_font = mfont (); - MFont *thai_font = mfont (); - MFont *tib_font = mfont (); - MFontset *fontset; - MSymbol unicode_bmp = msymbol ("unicode-bmp"); - MSymbol no_ctl = msymbol ("no-ctl"); - - mfont_put_prop (dev_font, Mfamily, msymbol ("raghindi")); - mfont_put_prop (dev_font, Mregistry, unicode_bmp); - mfont_put_prop (thai_font, Mfamily, msymbol ("norasi")); - mfont_put_prop (thai_font, Mregistry, unicode_bmp); - mfont_put_prop (tib_font, Mfamily, msymbol ("mtib")); - mfont_put_prop (tib_font, Mregistry, unicode_bmp); - - fontset = mfontset_copy (mfontset (fontset_name), "no-ctl"); - mfontset_modify_entry (fontset, msymbol ("latin"), Mnil, Mnil, - latin_font, Mnil, 0); - mfontset_modify_entry (fontset, msymbol ("devanagari"), Mnil, Mnil, - dev_font, no_ctl, 0); - mfontset_modify_entry (fontset, msymbol ("thai"), Mnil, Mnil, - thai_font, no_ctl, 0); - mfontset_modify_entry (fontset, msymbol ("tibetan"), Mnil, Mnil, - tib_font, no_ctl, 0); - face_no_ctl_fontset = mface (); - mface_put_prop (face_no_ctl_fontset, Mfontset, fontset); - m17n_object_unref (fontset); - - free (dev_font); - free (thai_font); - free (tib_font); - } - - setup_input_methods (with_xim); - - gc = DefaultGC (display, screen); - - XtSetArg (arg[0], XtNtranslations, XtParseTranslationTable (trans2)); - XtSetArg (arg[1], XtNdefaultDistance, 2); - form = XtCreateManagedWidget ("form", formWidgetClass, ShellWidget, arg, 2); - - XtSetArg (arg[0], XtNborderWidth, 0); - XtSetArg (arg[1], XtNdefaultDistance, 2); - XtSetArg (arg[2], XtNtop, XawChainTop); - XtSetArg (arg[3], XtNbottom, XawChainTop); - XtSetArg (arg[4], XtNleft, XawChainLeft); - XtSetArg (arg[5], XtNright, XawChainRight); - XtSetArg (arg[6], XtNresizable, True); - HeadWidget = XtCreateManagedWidget ("head", formWidgetClass, form, arg, 7); - XtSetArg (arg[7], XtNfromVert, HeadWidget); - FaceWidget = XtCreateManagedWidget ("face", formWidgetClass, form, arg, 8); - XtSetArg (arg[7], XtNfromVert, FaceWidget); - LangWidget = XtCreateManagedWidget ("lang", formWidgetClass, form, arg, 8); - XtSetArg (arg[3], XtNbottom, XawChainBottom); - XtSetArg (arg[7], XtNfromVert, LangWidget); - BodyWidget = XtCreateManagedWidget ("body", formWidgetClass, form, arg, 8); - XtSetArg (arg[2], XtNtop, XawChainBottom); - XtSetArg (arg[7], XtNfromVert, BodyWidget); - TailWidget = XtCreateManagedWidget ("tail", formWidgetClass, form, arg, 8); - - FileShellWidget = XtCreatePopupShell ("FileShell", transientShellWidgetClass, - HeadWidget, NULL, 0); - XtSetArg (arg[0], XtNvalue, ""); - FileDialogWidget = XtCreateManagedWidget ("File", dialogWidgetClass, - FileShellWidget, arg, 1); - XawDialogAddButton (FileDialogWidget, "OK", - FileDialogProc, (XtPointer) 0); - XawDialogAddButton (FileDialogWidget, "CANCEL", - FileDialogProc, (XtPointer) 1); - - CheckPixmap = XCreateBitmapFromData (display, RootWindow (display, screen), - (char *) check_bits, - check_width, check_height); - { - unsigned long valuemask = GCForeground; - XGCValues values; - - values.foreground = 1; - mono_gc = XCreateGC (display, CheckPixmap, valuemask, &values); - values.foreground = 0; - mono_gc_inv = XCreateGC (display, CheckPixmap, valuemask, &values); - } - - { - MenuRec *menus; - int num_menus = 10; - - if (num_menus < num_input_methods + 2) - num_menus = num_input_methods + 2; - if (num_menus < num_faces + 1) - num_menus = num_faces + 1; - menus = alloca (sizeof (MenuRec) * num_menus); - - w = create_menu_button (ShellWidget, HeadWidget, NULL, "File", "File Menu", - FileMenu, sizeof FileMenu / sizeof (MenuRec), - "File I/O, Serialization, Image, Quit"); - - SetMenu (menus[0], 0, "Logical Move", NULL, CursorProc, 0, 1); - SetMenu (menus[1], 0, "Visual Move", NULL, CursorProc, 1, 0); - SetMenu (menus[2], 1, "", NULL, NULL, NULL, 0); - SetMenu (menus[3], 0, "Box type", NULL, CursorProc, 2, 0); - SetMenu (menus[4], 0, "Bar type", NULL, CursorProc, 3, 1); - SetMenu (menus[5], 0, "Bidi type", NULL, CursorProc, 4, 0); - w = create_menu_button (ShellWidget, HeadWidget, w, - "Cursor", "Cursor Menu", - menus, 6, "Cursor Movement Mode, Cursor Shape"); - CursorMenus[0] = menus[0].w; - CursorMenus[1] = menus[1].w; - CursorMenus[2] = menus[3].w; - CursorMenus[3] = menus[4].w; - CursorMenus[4] = menus[5].w; - - SetMenu (menus[0], 0, "disable", NULL, BidiProc, 0, 0); - SetMenu (menus[1], 0, "Left (|--> |)", NULL, BidiProc, 1, 1); - SetMenu (menus[2], 0, "Right (| <--|)", NULL, BidiProc, 2, 0); - w = create_menu_button (ShellWidget, HeadWidget, w, "Bidi", "Bidi Menu", - menus, 3, "BIDI Processing Mode"); - for (i = 0; i < 3; i++) - BidiMenus[i] = menus[i].w; - - SetMenu (menus[0], 0, "truncate", NULL, LineBreakProc, 0, 0); - SetMenu (menus[1], 0, "break at edge", NULL, LineBreakProc, 1, 1); - SetMenu (menus[2], 0, "break at word boundary", NULL, LineBreakProc, 2, 0); - w = create_menu_button (ShellWidget, HeadWidget, w, "LineBreak", - "LineBreak Menu", - menus, 3, "How to break lines"); - for (i = 0; i < 3; i++) - LineBreakMenus[i] = menus[i].w; - - SetMenu (menus[0], 0, "none", NULL, InputMethodProc, -2, 1); - SetMenu (menus[1], 0, "auto", NULL, InputMethodProc, -1, 0); - for (i = 0; i < num_input_methods; i++) - { - MInputMethod *im = input_method_table[i]; - char *name1, *name2; - - if (im->language != Mnil && im->language != Mt) - { - MSymbol sym = msymbol_get (im->language, Mlanguage); - if (sym == Mnil) - name1 = msymbol_name (im->language); - else - name1 = msymbol_name (sym); - name2 = msymbol_name (im->name); - } - else - name1 = msymbol_name (im->name), name2 = NULL; - - SetMenu (menus[i + 2], 0, name1, name2, InputMethodProc, i, 0); - } - w = create_menu_button (ShellWidget, HeadWidget, w, "InputMethod", - "Input Method Menu", menus, i + 2, - "Select input method"); - - { - unsigned long valuemask = GCForeground; - XGCValues values; - - XtSetArg (arg[0], XtNbackground, &values.foreground); - XtGetValues (w, arg, 1); - gc_inv = XCreateGC (display, RootWindow (display, screen), - valuemask, &values); - } - - InputMethodMenus = malloc (sizeof (Widget) * (num_input_methods + 2)); - for (i = 0; i < num_input_methods + 2; i++) - InputMethodMenus[i] = menus[i].w; - - input_status_width = font_width * 8; - input_status_height = (font_ascent + font_descent) * 2.4; - input_status_pixmap = XCreatePixmap (display, RootWindow (display, screen), - input_status_width, - input_status_height, - DefaultDepth (display, screen)); - { - MFaceBoxProp prop; - - prop.width = 1; - prop.color_top = prop.color_bottom - = prop.color_left = prop.color_right = Mnil; - prop.inner_hmargin = prop.inner_vmargin = 1; - prop.outer_hmargin = prop.outer_vmargin = 0; - face_input_status = mface (); - mface_put_prop (face_input_status, Mbox, &prop); - } - - XFillRectangle (display, input_status_pixmap, gc_inv, - 0, 0, input_status_width, input_status_height); - XtSetArg (arg[0], XtNfromHoriz, w); - XtSetArg (arg[1], XtNleft, XawRubber); - XtSetArg (arg[2], XtNright, XawChainRight); - XtSetArg (arg[3], XtNborderWidth, 0); - XtSetArg (arg[4], XtNlabel, " "); - XtSetArg (arg[5], XtNjustify, XtJustifyRight); - CurIMLang = XtCreateManagedWidget ("CurIMLang", labelWidgetClass, - HeadWidget, arg, 6); - XtSetArg (arg[0], XtNfromHoriz, CurIMLang); - XtSetArg (arg[1], XtNleft, XawChainRight); - XtSetArg (arg[4], XtNbitmap, input_status_pixmap); - CurIMStatus = XtCreateManagedWidget ("CurIMStatus", labelWidgetClass, - HeadWidget, arg, 5); - - XtSetArg (arg[0], XtNborderWidth, 0); - XtSetArg (arg[1], XtNleft, XawChainLeft); - XtSetArg (arg[2], XtNright, XawChainLeft); - w = XtCreateManagedWidget ("Face", labelWidgetClass, FaceWidget, arg, 3); - for (i = 0; i < num_faces;) - { - char *label_menu = face_table[i++].name; /* "Menu Xxxx" */ - char *label = label_menu + 5; /* "Xxxx" */ - - for (j = i; j < num_faces && face_table[j].face; j++) - SetMenu (menus[j - i], 0, face_table[j].name, NULL, - FaceProc, j, -1); - w = create_menu_button (ShellWidget, FaceWidget, w, - label, label_menu, - menus, j - i, "Push face property"); - i = j; - } - - XtSetArg (arg[0], XtNfromHoriz, w); - XtSetArg (arg[1], XtNleft, XawChainLeft); - XtSetArg (arg[2], XtNright, XawChainLeft); - XtSetArg (arg[3], XtNhorizDistance, 10); - XtSetArg (arg[4], XtNlabel, "Pop"); - XtSetArg (arg[5], XtNtranslations, - XtParseTranslationTable (pop_face_trans)); - w = XtCreateManagedWidget ("Pop Face", commandWidgetClass, - FaceWidget, arg, 6); - XtAddCallback (w, XtNcallback, FaceProc, (void *) -1); - - XtSetArg (arg[0], XtNfromHoriz, w); - XtSetArg (arg[1], XtNleft, XawChainLeft); - XtSetArg (arg[2], XtNright, XawChainRight); - XtSetArg (arg[3], XtNlabel, ""); - XtSetArg (arg[4], XtNborderWidth, 0); - XtSetArg (arg[5], XtNjustify, XtJustifyRight); - CurFaceWidget = XtCreateManagedWidget ("Current Face", labelWidgetClass, - FaceWidget, arg, 6); - - XtSetArg (arg[0], XtNborderWidth, 0); - XtSetArg (arg[1], XtNleft, XawChainLeft); - XtSetArg (arg[2], XtNright, XawChainLeft); - w = XtCreateManagedWidget ("Lang", labelWidgetClass, LangWidget, arg, 3); - { - MPlist *plist[11], *pl; - char langname[3]; - - for (i = 0; i < 11; i++) plist[i] = NULL; - langname[2] = '\0'; - for (langname[0] = 'a'; langname[0] <= 'z'; langname[0]++) - for (langname[1] = 'a'; langname[1] <= 'z'; langname[1]++) - { - MSymbol sym = msymbol_exist (langname); - MSymbol fullname; - - if (sym != Mnil - && ((fullname = msymbol_get (sym, Mlanguage)) != Mnil)) - { - char *name = msymbol_name (fullname); - char c = name[0]; - - if (c >= 'A' && c <= 'Z') - { - int idx = (c < 'U') ? (c - 'A') / 2 : 10; - - pl = plist[idx]; - if (! pl) - pl = plist[idx] = mplist (); - for (; mplist_next (pl); pl = mplist_next (pl)) - if (strcmp (name, (char *) mplist_value (pl)) < 0) - break; - mplist_push (pl, sym, fullname); - } - } - } - - for (i = 0; i < 11; i++) - if (plist[i]) - { - char *name = malloc (9); - - sprintf (name, "Menu %c-%c", 'A' + i * 2, 'A' + i * 2 + 1); - if (i == 10) - name[7] = 'Z'; - for (j = 0, pl = plist[i]; mplist_next (pl); - j++, pl = mplist_next (pl)) - SetMenu (menus[j], 0, msymbol_name ((MSymbol) mplist_value (pl)), - msymbol_name (mplist_key (pl)), - LangProc, mplist_key (pl), -1); - w = create_menu_button (ShellWidget, LangWidget, w, name + 5, name, - menus, j, "Push language property"); - } - for (i = 0; i < 11; i++) - if (plist[i]) - m17n_object_unref (plist[i]); - } - XtSetArg (arg[0], XtNfromHoriz, w); - XtSetArg (arg[1], XtNleft, XawChainLeft); - XtSetArg (arg[2], XtNright, XawChainLeft); - XtSetArg (arg[3], XtNhorizDistance, 10); - XtSetArg (arg[4], XtNlabel, "Pop"); - XtSetArg (arg[5], XtNtranslations, - XtParseTranslationTable (pop_lang_trans)); - w = XtCreateManagedWidget ("Pop Lang", commandWidgetClass, - LangWidget, arg, 6); - XtAddCallback (w, XtNcallback, LangProc, Mnil); - - XtSetArg (arg[0], XtNfromHoriz, w); - XtSetArg (arg[1], XtNleft, XawChainLeft); - XtSetArg (arg[2], XtNright, XawChainRight); - XtSetArg (arg[3], XtNlabel, ""); - XtSetArg (arg[4], XtNborderWidth, 0); - XtSetArg (arg[5], XtNjustify, XtJustifyRight); - CurLangWidget = XtCreateManagedWidget ("Current Lang", labelWidgetClass, - LangWidget, arg, 6); - } - - XtSetArg (arg[0], XtNheight, win_height); - XtSetArg (arg[1], XtNwidth, 10); - XtSetArg (arg[2], XtNleft, XawChainLeft); - XtSetArg (arg[3], XtNright, XawChainLeft); - SbarWidget = XtCreateManagedWidget ("sbar", scrollbarWidgetClass, BodyWidget, - arg, 4); - XtAddCallback (SbarWidget, XtNscrollProc, ScrollProc, NULL); - XtAddCallback (SbarWidget, XtNjumpProc, JumpProc, NULL); - - XtSetArg (arg[0], XtNheight, win_height); - XtSetArg (arg[1], XtNwidth, win_width); - XtSetArg (arg[2], XtNtranslations, XtParseTranslationTable (trans)); - XtSetArg (arg[3], XtNfromHoriz, SbarWidget); - XtSetArg (arg[4], XtNleft, XawChainLeft); - XtSetArg (arg[5], XtNright, XawChainRight); - TextWidget = XtCreateManagedWidget ("text", simpleWidgetClass, BodyWidget, - arg, 5); - - XtSetArg (arg[0], XtNborderWidth, 0); - XtSetArg (arg[1], XtNleft, XawChainLeft); - XtSetArg (arg[2], XtNright, XawChainRight); - XtSetArg (arg[3], XtNresizable, True); - XtSetArg (arg[4], XtNjustify, XtJustifyLeft); - MessageWidget = XtCreateManagedWidget ("message", labelWidgetClass, - TailWidget, arg, 5); - - memset (&control, 0, sizeof control); - control.two_dimensional = 1; - control.enable_bidi = 1; - control.min_line_ascent = font_ascent; - control.min_line_descent = font_descent; - control.max_line_width = win_width; - control.with_cursor = 1; - control.cursor_width = 2; - control.partial_update = 1; - control.ignore_formatting_char = 1; - - XtAppAddActions (context, actions, XtNumber (actions)); - XtRealizeWidget (ShellWidget); - - win = XtWindow (TextWidget); - - XtAppMainLoop (context); - - if (current_input_context) - minput_destroy_ic (current_input_context); - for (i = 0; i < num_input_methods; i++) - minput_close_im (input_method_table[i]); - m17n_object_unref (frame); - - m17n_object_unref (mt); - m17n_object_unref (face_xxx_large); - m17n_object_unref (face_box); - m17n_object_unref (face_courier); - m17n_object_unref (face_helvetica); - m17n_object_unref (face_times); - m17n_object_unref (face_dv_ttyogesh); - m17n_object_unref (face_freesans); - m17n_object_unref (face_freemono); - m17n_object_unref (face_default_fontset); - m17n_object_unref (face_no_ctl_fontset); - m17n_object_unref (face_input_status); - m17n_object_unref (selection); - - M17N_FINI (); - - free (fontset_name); - - XtUninstallTranslations (form); - XtUninstallTranslations (TextWidget); - XtDestroyWidget (ShellWidget); - XtDestroyApplicationContext (context); - - exit (0); -} -#endif /* not FOR_DOXYGEN */ diff --git a/example/mimx-anthy.c b/example/mimx-anthy.c deleted file mode 100644 index 518abb8..0000000 --- a/example/mimx-anthy.c +++ /dev/null @@ -1,330 +0,0 @@ -/* mimx-anthy.c -- Input method external module for Anthy. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -/***en - @page mimx-anthy external module for the input method - - @section mimx-anthy-description DESCRIPTION - - The shared library mimx-anthy.so is an external module used by the - input method . It exports these functions. - -
    -
  • init - - Initialize this module. - -
  • fini - - Finalize this module. - -
  • convert - - Convert the current preedit text (Hiragana sequence) into - Kana-Kanji mixed text. - -
  • change - - Record the change of candidate of the current segment. - -
  • resize - - Enlarge or shorten the length of the current segment. - -
  • commit - - Commit the lastly selected candidates of all the segments. - -
- - @section mimx-anthy-seealso See also - @ref mdbIM -*/ - -#ifndef FOR_DOXYGEN - -#include -#include -#include -#include - -#ifdef HAVE_ANTHY - -#include - -static int initialized; -static MSymbol Manthy, Msegment; - -/* A structure to record in MInputContext->plist with key Manthy. */ - -typedef struct { - anthy_context_t ac; - /* Which candidate is selected in each segment. */ - int *candidate_numbers; - /* Size of the above array. */ - int num_segments; - /* Converter for this context. */ - MConverter *converter; -} AnthyContext; - -static AnthyContext * -new_context (MInputContext *ic) -{ - AnthyContext *context = NULL; - MSymbol euc_jp = msymbol ("euc-jp"); - /* Rebound to an actual buffer just before being used. */ - MConverter *converter = mconv_buffer_converter (euc_jp, NULL, 0); - - if (converter) - { - context = calloc (1, sizeof (AnthyContext)); - context->ac = anthy_create_context (); - context->num_segments = 0; - context->candidate_numbers = NULL; - context->converter = converter; - } - return context; -} - -static void -free_context (AnthyContext *context) -{ - anthy_release_context (context->ac); - if (context->candidate_numbers) - free (context->candidate_numbers); - mconv_free_converter (context->converter); - free (context); -} - -static void -allocate_candidate_numbers (AnthyContext *context, int num) -{ - if (context->num_segments < num) - { - if (context->num_segments == 0) - context->candidate_numbers = malloc (sizeof (int) * num); - else - context->candidate_numbers = realloc (context->candidate_numbers, - sizeof (int) * num); - context->num_segments = num; - } -} - -static void -add_action (MPlist *actions, MSymbol name, MSymbol key, void *val) -{ - MPlist *action = mplist (); - - mplist_add (action, Msymbol, name); - mplist_add (action, key, val); - mplist_add (actions, Mplist, action); - m17n_object_unref (action); -} - -/* Return a list of all candidates of the Nth segment. The return - value is a plist whose elements are plists who contains at most 5 - candidates. */ - -static MPlist * -make_candidate_list (AnthyContext *context, int n) -{ - MPlist *plist = mplist (), *pl; - int i; - char buf[1024]; - struct anthy_segment_stat ss; - MText *mt; - - anthy_get_segment_stat (context->ac, n, &ss); - for (i = 0, pl = mplist (); i < ss.nr_candidate; i++) - { - anthy_get_segment (context->ac, n, i, buf, sizeof (buf)); - mconv_rebind_buffer (context->converter, - (unsigned char *) buf, strlen (buf)); - mt = mconv_decode (context->converter, mtext ()); - mtext_put_prop (mt, 0, mtext_len (mt), Msegment, (void *) (n + 1)); - mplist_add (pl, Mtext, mt); - m17n_object_unref (mt); - if (i % 5 == 4) - { - mplist_add (plist, Mplist, pl); - m17n_object_unref (pl); - pl = mplist (); - } - } - if (mplist_key (pl) != Mnil) - mplist_add (plist, Mplist, pl); - m17n_object_unref (pl); - return plist; -} - -MPlist * -init (MPlist *args) -{ - MInputContext *ic = mplist_value (args); - - if (! initialized) - { - anthy_init (); - Manthy = msymbol (" anthy"); - Msegment = msymbol (" segment"); - initialized = 1; - } - mplist_push (ic->plist, Manthy, new_context (ic)); - return NULL; -} - -MPlist * -fini (MPlist *args) -{ - MInputContext *ic = mplist_value (args); - AnthyContext *context = mplist_get (ic->plist, Manthy); - - if (context) - free_context (context); - return NULL; -} - -MPlist * -convert (MPlist *args) -{ - MInputContext *ic = mplist_value (args); - AnthyContext *context = mplist_get (ic->plist, Manthy); - struct anthy_conv_stat cs; - MPlist *action, *actions; - int i; - unsigned char buf[1024]; - - if (! context) - return NULL; - - mconv_rebind_buffer (context->converter, buf, sizeof (buf)); - mconv_encode (context->converter, ic->preedit); - buf[context->converter->nbytes] = '\0'; - anthy_set_string (context->ac, (char *) buf); - anthy_get_stat (context->ac, &cs); - allocate_candidate_numbers (context, cs.nr_segment); - - actions = mplist (); - add_action (actions, msymbol ("move"), Msymbol, msymbol ("@<")); - add_action (actions, msymbol ("delete"), Msymbol, msymbol ("@>")); - for (i = 0; i < cs.nr_segment; i++) - { - context->candidate_numbers[i] = 0; - if (i == 1) - add_action (actions, msymbol ("mark"), Msymbol, msymbol ("@anthy")); - action = make_candidate_list (context, i); - mplist_add (actions, Mplist, action); - m17n_object_unref (action); - } - if (cs.nr_segment > 1) - add_action (actions, msymbol ("move"), Msymbol, msymbol ("@anthy")); - - return actions; -} - -MPlist * -change (MPlist *args) -{ - MInputContext *ic = mplist_value (args); - AnthyContext *context = mplist_get (ic->plist, Manthy); - int segment; - - if (! context) - return NULL; - if (! ic->candidate_list || ic->cursor_pos == 0) - return NULL; - segment = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1, Msegment); - if (segment == 0) - return NULL; - segment--; - context->candidate_numbers[segment] = ic->candidate_index; - return NULL; -} - -MPlist * -resize (MPlist *args) -{ - MInputContext *ic = mplist_value (args); - AnthyContext *context = mplist_get (ic->plist, Manthy); - struct anthy_conv_stat cs; - MSymbol shorten; - int segment; - MPlist *actions, *action; - int i; - - if (! context) - return NULL; - if (! ic->candidate_list || ic->cursor_pos == 0) - return NULL; - segment = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1, Msegment); - if (segment == 0) - return NULL; - segment--; - args = mplist_next (args); - shorten = mplist_value (args); - anthy_resize_segment (context->ac, segment, shorten == Mt ? -1 : 1); - anthy_get_stat (context->ac, &cs); - allocate_candidate_numbers (context, cs.nr_segment); - - actions = mplist (); - if (segment == 0) - add_action (actions, msymbol ("move"), Msymbol, msymbol ("@<")); - else - add_action (actions, msymbol ("move"), Msymbol, msymbol ("@[")); - add_action (actions, msymbol ("delete"), Msymbol, msymbol ("@>")); - for (i = segment; i < cs.nr_segment; i++) - { - context->candidate_numbers[i] = 0; - if (i == segment + 1) - add_action (actions, msymbol ("mark"), Msymbol, msymbol ("@anthy")); - action = make_candidate_list (context, i); - mplist_add (actions, Mplist, action); - m17n_object_unref (action); - } - if (segment + 1 < cs.nr_segment) - add_action (actions, msymbol ("move"), Msymbol, msymbol ("@anthy")); - return actions; -} - -MPlist * -commit (MPlist *args) -{ - MInputContext *ic = mplist_value (args); - AnthyContext *context = mplist_get (ic->plist, Manthy); - struct anthy_conv_stat cs; - int i; - - anthy_get_stat (context->ac, &cs); - for (i = 0; i < cs.nr_segment; i++) - anthy_commit_segment (context->ac, i, context->candidate_numbers[i]); - return NULL; -} - -#else /* not HAVE_ANTHY */ - -MPlist *convert (MPlist *args) { return NULL; } -MPlist *change (MPlist *args) { return NULL; } -MPlist *resize (MPlist *args) { return NULL; } -MPlist *commit (MPlist *args) { return NULL; } - -#endif /* not HAVE_ANTHY */ -#endif /* not FOR_DOXYGEN */ diff --git a/example/mimx-ispell.c b/example/mimx-ispell.c deleted file mode 100644 index c81b5fc..0000000 --- a/example/mimx-ispell.c +++ /dev/null @@ -1,202 +0,0 @@ -/* imx-ispell.c -- Input method external module for Ispell. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -/***en - @page mimx-ispell external module for the input method - - @section mimx-ispell-description DESCRIPTION - - The shared library mimx-ispell.so is an external module used by the - input method . It exports these functions. - -
    -
  • init - - Initialize this library. - -
  • fini - - Finalize this library. - -
  • ispell_word - - Check the spell of the current preedit text (English) and, if the - spell is incorrect, return a list of candidates. - -
- - This program is just for demonstrating how to write an external - module for an m17n input method, not for an actual use. - - @section mimx-ispell-seealso See also - @ref mdbIM -*/ - -#ifndef FOR_DOXYGEN - -#include -#include -#include -#include - -#ifdef HAVE_ISPELL - -static int initialized = 0; -static MFace *mface_overstrike = NULL; - -static MPlist * -add_action (MPlist *actions, MSymbol name, MSymbol key, void *val) -{ - MPlist *action = mplist (); - - mplist_add (action, Msymbol, name); - if (key != Mnil) - mplist_add (action, key, val); - mplist_add (actions, Mplist, action); - m17n_object_unref (action); - return actions; -} - -MPlist * -init (MPlist *args) -{ - if (! initialized++) - { - MFaceHLineProp hline; - - hline.type = MFACE_HLINE_STRIKE_THROUGH; - hline.width = 1; - hline.color = msymbol ("black"); - mface_overstrike = mface (); - mface_put_prop (mface_overstrike, Mhline, &hline); - } - return NULL; -} - -MPlist * -fini (MPlist *args) -{ - if (! --initialized) - m17n_object_unref (mface_overstrike); - return NULL; -} - -MPlist * -ispell_word (MPlist *args) -{ - MInputContext *ic; - unsigned char buf[256]; - int nbytes; - MPlist *actions, *candidates, *plist; - char command[256]; - char **words; - FILE *ispell; - char *p = (char *) buf; - int i, n; - MSymbol init_state; - MSymbol select_state; - MText *mt; - - ic = mplist_value (args); - args = mplist_next (args); - init_state = (MSymbol) mplist_value (args); - args = mplist_next (args); - select_state = (MSymbol) mplist_value (args); - nbytes = mconv_encode_buffer (Mcoding_us_ascii, ic->preedit, buf, 256); - - actions = mplist (); - - if (nbytes < 3) - return add_action (actions, msymbol ("shift"), Msymbol, init_state); - - buf[nbytes] = '\0'; - sprintf (command, "echo %s | ispell -a -m", (char *) buf); - ispell = popen (command, "r"); - if (! ispell) - return add_action (actions, msymbol ("shift"), Msymbol, init_state); - - /* Skip the heading line. */ - fgets (p, 256, ispell); - /* Read just 256 bytes, thus candidates listed after the first 256 - bytes are just ignored. */ - fgets (p, 256, ispell); - pclose (ispell); - p[strlen (p) - 1] = '\0'; - if (*p != '&' && *p != '#') - return add_action (actions, msymbol ("shift"), Msymbol, init_state); - - add_action (actions, msymbol ("delete"), Msymbol, msymbol ("@<")); - if (*p == '#') - { - mt = mtext_dup (ic->preedit); - mtext_push_prop (mt, 0, mtext_len (mt), Mface, mface_overstrike); - mplist_add (actions, Mtext, mt); - add_action (actions, msymbol ("shift"), Msymbol, init_state); - m17n_object_unref (mt); - return actions; - } - - p = strchr (p + 2, ' '); - if (sscanf (p, "%d", &n) != 1) - return add_action (actions, msymbol ("shift"), Msymbol, init_state); - words = alloca (sizeof (char *) * n); - p = strchr (p + 1, ' '); - p = strchr (p + 1, ' '); - for (i = 0; i < n - 1; i++) - { - words[i] = ++p; - p = strchr (p, ','); - if (! p) - { - n = i - 1; - break; - } - *p++ = '\0'; - } - words[i] = ++p; - candidates = mplist (); - for (i = 0; i < n; i++) - { - mt = mconv_decode_buffer (Mcoding_us_ascii, (unsigned char *) words[i], - strlen (words[i])); - mplist_add (candidates, Mtext, mt); - m17n_object_unref (mt); - } - mt = mtext_dup (ic->preedit); - mtext_push_prop (mt, 0, mtext_len (mt), Mface, mface_overstrike); - mplist_add (candidates, Mtext, mt); - m17n_object_unref (mt); - plist = mplist_add (mplist (), Mplist, candidates); - m17n_object_unref (candidates); - mplist_add (actions, Mplist, plist); - m17n_object_unref (plist); - add_action (actions, msymbol ("show"), Mnil, NULL); - add_action (actions, msymbol ("shift"), Msymbol, select_state); - return actions; -} - -#else /* not HAVE_ISPELL */ - -MPlist *ispell_word (MPlist *args) { return NULL; } - -#endif /* not HAVE_ISPELL */ -#endif /* not FOR_DOXYGEN */ diff --git a/example/mview.c b/example/mview.c deleted file mode 100644 index c5b02e0..0000000 --- a/example/mview.c +++ /dev/null @@ -1,384 +0,0 @@ -/* mview.c -- File viewer - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -/***en - @page mview view file - - @section mview-synopsis SYNOPSIS - - mview [ XT-OPTION ...] [ OPTION ... ] [ FILE ] - - @section mview-description DESCRIPTION - - Display FILE on a window. - - If FILE is omitted, the input is taken from standard input. - - XT-OPTIONs are standard Xt arguments (e.g. -fn, -fg). - - The following OPTIONs are available. - -
    - -
  • -e ENCODING - - ENCODING is the encoding of FILE (defaults to UTF-8). - -
  • -s FONTSIZE - - FONTSIZE is the fontsize in point. If ommited, it defaults to the - size of the default font defined in X resource. - -
  • --version - - Print version number. - -
  • -h, --help - - Print this message. - -
-*/ -#ifndef FOR_DOXYGEN - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define VERSION "1.0" - -/* Global m17n variables. */ -MFrame *frame; -MText *mt; -MDrawMetric metric; -MDrawControl control; - - -/* Callback procedure for "quit". */ - -void -QuitProc (Widget w, XtPointer client_data, XtPointer call_data) -{ - XtAppSetExitFlag (XtWidgetToApplicationContext (w)); -} - - -/* Move POS to the next line head in M-text MT whose length is LEN. - If POS is already on the last line, set POS to LEN. */ - -#define NEXTLINE(pos, len) \ - do { \ - pos = mtext_character (mt, pos, len, '\n'); \ - if (pos < 0) \ - pos = len; \ - else \ - pos++; \ - } while (0) - - -/* Action procedure for expose event. Redraw partial area of the - widget W. The area is specified in EVENT. */ - -static void -ExposeProc (Widget w, XEvent *event, String *str, Cardinal *num) -{ - XExposeEvent *expose = (XExposeEvent *) event; - int len = mtext_len (mt); - int pos, from, to; - int y = 0, yoff = 0; - MDrawMetric rect; - - /* We must update the area between the Y-positions expose->y and - (expose->y + expose->height). We ignore X-positions. */ - - /* At first, find the line that occupies the Y-position expose->y. - That is the first line to draw. */ - to = 0; - while (1) - { - from = to; - NEXTLINE (to, len); - mdraw_text_extents (frame, mt, from, to, &control, NULL, NULL, &rect); - if (to == len || y + rect.height > expose->y) - break; - y += rect.height; - } - /* The first character to draw is at position FROM. Remeber the - Y-position to start drawing. */ - yoff = y - rect.y; - - /* Next, find the line that occupies the Y-position (expose->y + - expose->height). That is the last line to draw. This time, we - enable caching to utilize it in the later drawing. */ - y += rect.height; - control.disable_caching = 0; - while (to < len && y < expose->y + expose->height) - { - pos = to; - NEXTLINE (to, len); - mdraw_text_extents (frame, mt, pos, to, &control, NULL, NULL, &rect); - y += rect.height; - } - - /* It is decided that we must draw from FROM to the previous - character of TO. */ - mdraw_text_with_control (frame, (MDrawWindow) XtWindow (w), - 0, yoff, mt, from, to, &control); - - /* Disable caching again. */ - control.disable_caching = 1; - - /* If the widget was vertically enlarged too much, shrink it. */ - if (metric.height < expose->y + expose->height) - { - Arg arg; - - XtSetArg (arg, XtNheight, metric.height); - XtSetValues (w, &arg, 0); - } -} - - -/* Print the usage of this program (the name is PROG), and exit with - EXIT_CODE. */ - -void -help_exit (char *prog, int exit_code) -{ - char *p = prog; - - while (*p) - if (*p++ == '/') - prog = p; - - printf ("Usage: %s [ XT-OPTION ...] [ OPTION ...] [ FILE ]\n", prog); - printf ("Display FILE on a window.\n"); - printf (" If FILE is omitted, the input is taken from standard input.\n"); - printf (" XT-OPTIONs are standard Xt arguments (e.g. -fn, -fg).\n"); - printf ("The following OPTIONs are available.\n"); - printf (" %-13s %s", "-e ENCODING", - "ENCODING is the encoding of FILE (defaults to UTF-8).\n"); - printf (" %-13s %s", "-s FONTSIZE", - "FONTSIZE is the fontsize in point.\n"); - printf ("\t\tIf ommited, it defaults to the size\n"); - printf ("\t\tof the default font defined in X resource.\n"); - printf (" %-13s %s", "--version", "print version number\n"); - printf (" %-13s %s", "-h, --help", "print this message\n"); - exit (exit_code); -} - - -/* Format MSG by FMT and print the result to the stderr, and exit. */ - -#define FATAL_ERROR(fmt, arg) \ - do { \ - fprintf (stderr, fmt, arg); \ - exit (1); \ - } while (0) - - -/* Adjust FONTSIZE for the resolution of the screen of widget W. */ - -int -adjust_fontsize (Widget w, int fontsize) -{ - Display *display = XtDisplay (w); - int screen_number = XScreenNumberOfScreen (XtScreen (w)); - double pixels = DisplayHeight (display, screen_number); - double mm = DisplayHeightMM (display, screen_number); - - return (fontsize * pixels * 25.4 / mm / 100); -} - - -int -main (int argc, char **argv) -{ - XtAppContext context; - Widget shell, form, quit, viewport, text; - String quit_action = "q: set() notify() unset()"; - XtActionsRec actions[] = { {"Expose", ExposeProc} }; - Arg arg[10]; - int i; - int viewport_width, viewport_height; - char *coding_name = NULL; - FILE *fp = stdin; - MSymbol coding; - int fontsize = 0; - - /* Open an application context. */ - XtSetLanguageProc (NULL, NULL, NULL); - shell = XtOpenApplication (&context, "MView", NULL, 0, &argc, argv, NULL, - sessionShellWidgetClass, NULL, 0); - XtAppAddActions (context, actions, XtNumber (actions)); - - /* Parse the remaining command line arguments. */ - for (i = 1; i < argc; i++) - { - if (! strcmp (argv[i], "--help") - || ! strcmp (argv[i], "-h")) - help_exit (argv[0], 0); - else if (! strcmp (argv[i], "--version")) - { - printf ("mview (m17n library) %s\n", VERSION); - printf ("Copyright (C) 2003 AIST, JAPAN\n"); - exit (0); - } - else if (! strcmp (argv[i], "-e")) - { - i++; - coding_name = argv[i]; - } - else if (! strcmp (argv[i], "-s")) - { - double n; - i++; - n = atof (argv[i]); - if (n <= 0) - FATAL_ERROR ("Invalid fontsize %s!\n", argv[i]); - fontsize = adjust_fontsize (shell, (int) (n * 10)); - } - else if (argv[i][0] != '-') - { - fp = fopen (argv[i], "r"); - if (! fp) - FATAL_ERROR ("Fail to open the file %s!\n", argv[i]); - } - else - { - printf ("Unknown option: %s", argv[i]); - help_exit (argv[0], 1); - } - } - - /* Initialize the m17n library. */ - M17N_INIT (); - if (merror_code != MERROR_NONE) - FATAL_ERROR ("%s\n", "Fail to initialize the m17n library."); - - /* Decide how to decode the input stream. */ - if (coding_name) - { - coding = mconv_resolve_coding (msymbol (coding_name)); - if (coding == Mnil) - FATAL_ERROR ("Invalid coding: %s\n", coding_name); - } - else - coding = Mcoding_utf_8; - - mt = mconv_decode_stream (coding, fp); - fclose (fp); - if (! mt) - FATAL_ERROR ("%s\n", "Fail to decode the input file or stream!"); - - { - MPlist *param = mplist (); - MFace *face = mface (); - - if (fontsize) - mface_put_prop (face, Msize, (void *) fontsize); - mplist_put (param, Mwidget, shell); - mplist_put (param, Mface, face); - frame = mframe (param); - m17n_object_unref (param); - m17n_object_unref (face); - } - - /* Create this widget hierarchy. - Shell - form -+- quit - | - +- viewport - text */ - - form = XtCreateManagedWidget ("form", formWidgetClass, shell, NULL, 0); - XtSetArg (arg[0], XtNleft, XawChainLeft); - XtSetArg (arg[1], XtNright, XawChainLeft); - XtSetArg (arg[2], XtNtop, XawChainTop); - XtSetArg (arg[3], XtNbottom, XawChainTop); - XtSetArg (arg[4], XtNaccelerators, XtParseAcceleratorTable (quit_action)); - quit = XtCreateManagedWidget ("quit", commandWidgetClass, form, arg, 5); - XtAddCallback (quit, XtNcallback, QuitProc, NULL); - - viewport_width = (int) mframe_get_prop (frame, Mfont_width) * 80; - viewport_height - = ((int) mframe_get_prop (frame, Mfont_ascent) - + (int) mframe_get_prop (frame, Mfont_descent)) * 24; - XtSetArg (arg[0], XtNallowVert, True); - XtSetArg (arg[1], XtNforceBars, False); - XtSetArg (arg[2], XtNfromVert, quit); - XtSetArg (arg[3], XtNtop, XawChainTop); - XtSetArg (arg[4], XtNbottom, XawChainBottom); - XtSetArg (arg[5], XtNright, XawChainRight); - XtSetArg (arg[6], XtNwidth, viewport_width); - XtSetArg (arg[7], XtNheight, viewport_height); - viewport = XtCreateManagedWidget ("viewport", viewportWidgetClass, form, - arg, 8); - - /* Before creating the text widget, we must calculate the height of - the M-text to draw. */ - control.two_dimensional = 1; - control.enable_bidi = 1; - control.disable_caching = 1; - control.max_line_width = viewport_width; - mdraw_text_extents (frame, mt, 0, mtext_len (mt), &control, - NULL, NULL, &metric); - - { - /* Decide the size of the text widget. */ - XtSetArg (arg[0], XtNwidth, viewport_width); - if (viewport_height > metric.height) - /* The outer viewport is tall enough. */ - XtSetArg (arg[1], XtNheight, viewport_height); - else if (metric.height < 0x8000) - /* The M-text height is within the limit of X. */ - XtSetArg (arg[1], XtNheight, metric.height); - else - /* We can't make such a tall widget. Truncate it. */ - XtSetArg (arg[1], XtNheight, 0x7FFF); - - /* We must provide our own expose event handler. */ - XtSetArg (arg[2], XtNtranslations, - XtParseTranslationTable ((String) ": Expose()")); - text = XtCreateManagedWidget ("text", simpleWidgetClass, viewport, arg, 3); - } - - /* Realize the top widget, and dive into an even loop. */ - XtInstallAllAccelerators (form, form); - XtRealizeWidget (shell); - XtAppMainLoop (context); - - /* Clear away. */ - m17n_object_unref (mt); - m17n_object_unref (frame); - M17N_FINI (); - - exit (0); -} -#endif /* not FOR_DOXYGEN */ diff --git a/m17n-config.in b/m17n-config.in deleted file mode 100644 index a04d3eb..0000000 --- a/m17n-config.in +++ /dev/null @@ -1,105 +0,0 @@ -#!/bin/sh -# m17n-config -- helper script for the m17n library. -*- coding: euc-jp; -*- -# Copyright (C) 2003, 2004 -# National Institute of Advanced Industrial Science and Technology (AIST) -# Registration Number H15PRO112 -# See the end for copying conditions. - -prefix=@prefix@ -exec_prefix=@exec_prefix@ - -help () -{ - echo "Usage: $0 [CORE | X] [--version | --cflags | --libs | --libtool]" -} - -if test $# -eq 0; then - help 1>&2 - exit 0 -fi - -LIBNAME=m17n - -case $1 in -CORE) LIBNAME=m17n-core; shift;; -X) LIBNAME=m17n-X; shift;; -esac - -case $1 in ---version) - echo "@PACKAGE_VERSION@";; - ---libs) - if test "@libdir@" != "/usr/lib"; then - echo "-L@libdir@ -l${LIBNAME}" - else - echo "-lm17n-X" - fi;; - ---cflags) - if test "@includedir@" != "/usr/include"; then - echo "-I@includedir@" - fi;; - ---libtool) - echo "@libdir@/lib${LIBNAME}.la" - ;; - -*) - help - exit 1;; -esac -exit 0 - -cat > /dev/null < - - * Version 1.0 released. - - -Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - -This file is part of the m17n library. - -The m17n library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public License -as published by the Free Software Foundation; either version 2.1 of -the License, or (at your option) any later version. - -The m17n library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with the m17n library; if not, write to the Free -Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307, USA. diff --git a/src/Makefile.am b/src/Makefile.am deleted file mode 100644 index e87399f..0000000 --- a/src/Makefile.am +++ /dev/null @@ -1,89 +0,0 @@ -# Copyright (C) 2003, 2004 -# National Institute of Advanced Industrial Science and Technology (AIST) -# Registration Number H15PRO112 - -# This file is part of the m17n library. - -# The m17n library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public License -# as published by the Free Software Foundation; either version 2.1 of -# the License, or (at your option) any later version. - -# The m17n library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. - -# You should have received a copy of the GNU Lesser General Public -# License along with the m17n library; if not, write to the Free -# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -# 02111-1307, USA. - -lib_LTLIBRARIES = libm17n-core.la libm17n.la libm17n-X.la - -libm17n_core_la_SOURCES = \ - character.h character.c \ - chartab.h chartab.c \ - internal.h \ - plist.h plist.c \ - m17n-core.h m17n-core.c \ - m17n-misc.h \ - mtext.h mtext.c \ - symbol.h symbol.c \ - textprop.h textprop.c - -libm17n_core_la_LDFLAGS = @XML2_LD_FLAGS@ - -libm17n_la_SOURCES = \ - charset.h charset.c \ - coding.h coding.c \ - database.h database.c \ - input.h input.c \ - language.h language.c \ - mlocale.h locale.c \ - m17n.h m17n.c -libm17n_la_LIBADD = libm17n-core.la -libm17n_la_LDFLAGS = -ldl - -GUI_SOURCES = \ - face.h face.c \ - font.h font.c font-ft.c font-flt.c \ - fontset.h fontset.c \ - draw.c \ - input-gui.c \ - internal-gui.h \ - m17n-gui.h m17n-gui.c - -X_LD_FLAGS = ${X_PRE_LIBS} ${X_LIBS} -lX11 -lXt ${X_EXTRA_LIBS} -OPTIONAL_LD_FLAGS = @FRIBIDI_LD_FLAGS@ @FREETYPE_LD_FLAGS@ @OTF_LD_FLAGS@ - -libm17n_X_la_SOURCES = ${GUI_SOURCES} m17n-X.h m17n-X.c -libm17n_X_la_LIBADD = libm17n.la -libm17n_X_la_LDFLAGS = ${X_LD_FLAGS} ${OPTIONAL_LD_FLAGS} - -include_HEADERS = m17n-core.h m17n.h m17n-misc.h m17n-gui.h m17n-X.h - -AM_CPPFLAGS = -DM17NDIR="\"$(datadir)/m17n\"" - -bin_PROGRAMS = linkcore linkshell linkgui - -linkcore_SOURCES = linkcore.c -linkcore_LDADD = libm17n-core.la -linkcore_LDFLAGS = -static - -linkshell_SOURCES = linkshell.c -linkshell_LDADD = libm17n.la -linkshell_LDFLAGS = -static - -linkgui_SOURCES = linkgui.c -linkgui_LDADD = libm17n-X.la -#linkgui_LDFLAGS = -static - -# We should not install the above test programs. -install-binPROGRAMS: -uninstall-binPROGRAMS: - -SRC = ${libm17n_core_la_SOURCES} ${libm17n_la_SOURCES} ${libm17n_X_la_SOURCES} - -TAGS: ${SRC} - etags ${SRC} diff --git a/src/README b/src/README deleted file mode 100644 index afc3a7c..0000000 --- a/src/README +++ /dev/null @@ -1,23 +0,0 @@ -Naming convention. - -name-space internal external -========== ======== ======== -function mobject__xxx mobject_xxx -symbol variable Mobject__xxx Mobject_xxx -other variable mobject__xxx mobject_xxx -constant macro MOBJECT_XXX -other macro MOBJECT_XXX -type MObject[Xxx] - -A structure is named as MXxxxx and is `typedef'ed with the same name. -Ex: typedef struct MFace MFace - -In comments, a structure member is denoted simply as `', -but a member of a specific structure is denoted as -`MStruct->member_name'. If the member itself is a structure (or a -pointer to a structure) and has a sub-member, the sub-member is -denoted as: - `' - or `sub_name>' - or `MStruct->member_name.subname' - or `MStruct->member_name->subname' diff --git a/src/character.c b/src/character.c deleted file mode 100644 index c46cfa4..0000000 --- a/src/character.c +++ /dev/null @@ -1,517 +0,0 @@ -/* character.c -- character module. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -/***en - @addtogroup m17nCharacter - @brief Character objects and API for them. - - The m17n library represents a @e character by a character code (an - integer). The minimum character code is @c 0. The maximum - character code is defined by the macro #MCHAR_MAX. It is - assured that #MCHAR_MAX is not smaller than @c 0x3FFFFF (22 - bits). - - Characters @c 0 to @c 0x10FFFF are equivalent to the Unicode - characters of the same code values. - - A character can have zero or more properties called @e character - @e properties. A character property consists of a @e key and a - @e value, where key is a symbol and value is anything that can be - cast to (void *). "The character property that belongs - to character C and whose key is K" may be shortened to "the K - property of C". */ - -/***ja - @addtogroup m17nCharacter - @brief ʸ»ú¥ª¥Ö¥¸¥§¥¯¥È¤È¤½¤ì¤Ë´Ø¤¹¤ë API - - m17n ¥é¥¤¥Ö¥é¥ê¤Ï @e ʸ»ú ¤òʸ»ú¥³¡¼¥É¡ÊÀ°¿ô¡Ë¤Çɽ¸½¤¹¤ë¡£ºÇ¾®¤Îʸ - »ú¥³¡¼¥É¤Ï @c 0 ¤Ç¡¢ºÇÂç¤Îʸ»ú¥³¡¼¥É¤Ï¥Þ¥¯¥í #MCHAR_MAX ¤Ë¤è¤Ã¤Æ - ÄêµÁ¤µ¤ì¤Æ¤¤¤ë¡£#MCHAR_MAX ¤Ï @c 0x3FFFFF¡Ê22¥Ó¥Ã¥È¡Ë°Ê¾å¤Ç¤¢¤ë - ¤³¤È¤¬Êݾڤµ¤ì¤Æ¤¤¤ë¡£ - - @c 0 ¤«¤é @c 0x10FFFF ¤Þ¤Ç¤Îʸ»ú¤Ï¡¢¤½¤ì¤ÈƱ¤¸Ãͤò»ý¤Ä Unicode ¤Î - ʸ»ú¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¡£ - - ³Æʸ»ú¤Ï @e ʸ»ú¥×¥í¥Ñ¥Æ¥£ ¤È¸Æ¤Ö¥×¥í¥Ñ¥Æ¥£¤ò0¸Ä°Ê¾å»ý¤Ä¤³¤È¤¬¤Ç¤­ - ¤ë¡£Ê¸»ú¥×¥í¥Ñ¥Æ¥£¤Ï @e ¥­¡¼ ¤È @e ÃÍ ¤«¤é¤Ê¤ë¡£¥­¡¼¤Ï¥·¥ó¥Ü¥ë¤Ç¤¢ - ¤ê¡¢ÃÍ¤Ï (void *) ·¿¤Ë¥­¥ã¥¹¥È¤Ç¤­¤ë¤â¤Î¤Ê¤é²¿¤Ç¤â¤è¤¤¡£ - ¡Öʸ»ú C ¤Îʸ»ú¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¥­¡¼¤¬ @c K ¤Ç¤¢¤ë¤â¤Î¡×¤ò´Êñ¤Ë - ¡Öʸ»ú C ¤Î K ¥×¥í¥Ñ¥Æ¥£¡×¤È¸Æ¤Ö¤³¤È¤¬¤¢¤ë¡£ */ -/*=*/ - -#if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE) -/*** @addtogroup m17nInternal - @{ */ - -#include -#include -#include -#include -#include -#include - -#include "m17n-core.h" -#include "m17n-misc.h" -#include "internal.h" - -typedef struct -{ - MSymbol type; - void *mdb; - MCharTable *table; -} MCharPropRecord; - -static MPlist *char_prop_list; - -static void -free_string (int from, int to, void *str, void *arg) -{ - free (str); -} - - -/* Internal API */ - -int -mchar__init () -{ - char_prop_list = mplist (); - - Mname - = mchar_define_property ("name", Mstring); - Mcategory - = mchar_define_property ("category", Msymbol); - Mcombining_class - = mchar_define_property ("combining-class", Minteger); - Mbidi_category - = mchar_define_property ("bidirectional-category", Msymbol); - Msimple_case_folding - = mchar_define_property ("simple-case-folding", Minteger); - Mcomplicated_case_folding - = mchar_define_property ("complicated-case-folding", Mtext); - Mscript - = mchar_define_property ("script", Msymbol); - - return 0; -} - -void -mchar__fini (void) -{ - MPlist *p; - - for (p = char_prop_list; mplist_key (p) != Mnil; p = mplist_next (p)) - { - MCharPropRecord *record = mplist_value (p); - - if (record->table) - { - if (record->type == Mstring) - mchartable_map (record->table, NULL, free_string, NULL); - M17N_OBJECT_UNREF (record->table); - } - free (record); - } - M17N_OBJECT_UNREF (char_prop_list); -} - -/*** @} */ -#endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */ - -/* External API */ - -/*** @addtogroup m17nCharacter */ -/*** @{ */ -/*=*/ - -#ifdef FOR_DOXYGEN -/***en - @brief Maximum character code. - - The macro #MCHAR_MAX gives the maximum character code. */ - -/***ja - @brief ʸ»ú¥³¡¼¥É¤ÎºÇÂçÃÍ - - ¥Þ¥¯¥í #MCHAR_MAX ¤Ïʸ»ú¥³¡¼¥É¤ÎºÇÂçÃͤòÍ¿¤¨¤ë¡£ */ - -#define MCHAR_MAX -/*=*/ -#endif /* FOR_DOXYGEN */ - -/***en - @ingroup m17nCharacter - @name Variables: Keys of character properties - - These symbols are used as keys of character properties. */ - -/***ja - @name ÊÑ¿ô: ʸ»ú¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼ - - ¤³¤ì¤é¤Î¥·¥ó¥Ü¥ë¤Ïʸ»ú¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤Æ»È¤ï¤ì¤ë¡£*/ -/*=*/ -/*** @{ */ - -/***en - @brief Key for script. - - The symbol #Mscript has the name "script" and is used as the key - of a character property. The value of such a property is a symbol - representing the script to which the character belongs. - - Each symbol that represents a script has one of the names listed in - the Unicode Technical Report #24. */ - -/***ja - @brief ¥¹¥¯¥ê¥×¥È¤òɽ¤ï¤¹¥­¡¼ - - ¥·¥ó¥Ü¥ë #Mscript ¤Ï "script" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢Ê¸»ú¥× - ¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤Æ»È¤ï¤ì¤ë¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢¤³¤Îʸ»ú¤Î°¤¹ - ¤ë¥¹¥¯¥ê¥×¥È¤òɽ¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£ - - ¥¹¥¯¥ê¥×¥È¤òɽ¤ï¤¹¥·¥ó¥Ü¥ë¤Î̾Á°¤Ï¡¢Unicode Technical Report - #24 ¤Ë¥ê¥¹¥È¤µ¤ì¤Æ¤¤¤ë¤â¤Î¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£ */ - -MSymbol Mscript; - -/*=*/ - -/***en - @brief Key for character name. - - The symbol #Mname has the name "name" and is used as - the key of a character property. The value of such a property is a - C-string representing the name of the character. */ - -/***ja - @brief ̾Á°¤òɽ¤ï¤¹¥­¡¼ - - ¥·¥ó¥Ü¥ë #Mname ¤Ï "name" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢Ê¸»ú¥×¥í¥Ñ - ¥Æ¥£¤Î¥­¡¼¤È¤·¤Æ»È¤ï¤ì¤ë¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃÍ¤Ï C-string ¤Ç¤¢¤ê¡¢¤½ - ¤Îʸ»ú¤Î̾Á°¤òɽ¤ï¤¹¡£ */ - -MSymbol Mname; - -/*=*/ - -/***en - @brief Key for general category. - - The symbol #Mcategory has the name "category" and is - used as the key of a character property. The value of such a - property is a symbol representing the general category of - the character. - - Each symbol that represents a general category has one of the - names listed as abbreviations for General Category in - Unicode. */ - -/***ja - @brief °ìÈÌ¥«¥Æ¥´¥ê¤òɽ¤ï¤¹¥­¡¼ - - ¥·¥ó¥Ü¥ë #Mcategory ¤Ï "category" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢Ê¸ - »ú¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤Æ»È¤ï¤ì¤ë¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢Âбþ¤¹¤ë - °ìÈÌ¥«¥Æ¥´¥ê ¤òɽ¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£ - - °ìÈÌ¥«¥Æ¥´¥ê¤òɽ¤ï¤¹¥·¥ó¥Ü¥ë¤Î̾Á°¤Ï¡¢General Category¤Î - ¾Êά·Á¤È¤·¤Æ Unicode ¤ËÄêµÁ¤µ¤ì¤Æ¤¤¤ë¤â¤Î¤Ç¤¢¤ë¡£ */ - -MSymbol Mcategory; - -/*=*/ - -/***en - @brief Key for canonical combining class. - - The symbol #Mcombining_class has the name - "combining-class" and is used as the key of a character - property. The value of such a property is an integer that - represents the canonical combining class of the character. - - The meaning of each integer that represents a canonical combining - class is identical to the one defined in Unicode. */ - -/***ja - @brief ɸ½à·ë¹ç¥¯¥é¥¹¤òɽ¤ï¤¹¥­¡¼ - - ¥·¥ó¥Ü¥ë #Mcombining_class ¤Ï "combining-class" ¤È¤¤¤¦ - ̾Á°¤ò»ý¤Á¡¢Ê¸»ú¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤Æ»È¤ï¤ì¤ë¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃÍ - ¤Ï¡¢Âбþ¤¹¤ë @e ɸ½à·ë¹ç¥¯¥é¥¹ ¤òɽ¤ï¤¹ÈóÉéÀ°¿ô¤Ç¤¢¤ë¡£ - - ɸ½à·ë¹ç¥¯¥é¥¹¤òɽ¤ï¤¹ÈóÉéÀ°¿ô¤Î°ÕÌ£¤Ï¡¢Unicode ¤ËÄêµÁ¤µ¤ì¤Æ¤¤¤ë¤â¤Î - ¤ÈƱ¤¸¤Ç¤¢¤ë¡£ */ - -MSymbol Mcombining_class; -/*=*/ - -/***en - @brief Key for bidi category. - - The symbol #Mbidi_category has the name "bidi-category" - and is used as the key of a character property. The value of such - a property is a symbol that represents the bidirectional - category of the character. - - Each symbol that represents a bidirectional category has one of - the names listed as types of Bidirectional Category in - Unicode. */ - -/***ja - @brief ÁÐÊý¸þ¥«¥Æ¥´¥ê¤òɽ¤ï¤¹¥­¡¼ - - ¥·¥ó¥Ü¥ë #Mbidi_category ¤Ï "bidi-category" ¤È¤¤¤¦Ì¾Á° - ¤ò»ý¤Á¡¢Ê¸»ú¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤Æ»È¤ï¤ì¤ë¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢ - Âбþ¤¹¤ë @e ÁÐÊý¸þ¥«¥Æ¥´¥ê ¤òɽ¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£ - - ÁÐÊý¸þ¥«¥Æ¥´¥ê¤òɽ¤ï¤¹¥·¥ó¥Ü¥ë¤Î̾Á°¤Ï¡¢Bidirectional - Category ¤Î·¿¤È¤·¤Æ Unicode ¤ËÄêµÁ¤µ¤ì¤Æ¤¤¤ë¤â¤Î¤Ç¤¢¤ë¡£ */ - -MSymbol Mbidi_category; -/*=*/ - -/***en - @brief Key for corresponding single lowercase character. - - The symbol #Msimple_case_folding has the name - "simple-case-folding" and is used as the key of a - character property. The value of such a property is the - corresponding single lowercase character that is used when - comparing M-texts ignoring cases. - - If a character requires a complicated comparison (i.e. cannot be - compared by simply mapping to another single character), the value - of such a property is @c 0xFFFF. In this case, the character has - another property whose key is #Mcomplicated_case_folding. */ - -/***ja - @brief Âбþ¤¹¤ë¾®Ê¸»ú°ìʸ»ú¤òɽ¤ï¤¹¥­¡¼ - - ¥·¥ó¥Ü¥ë #Msimple_case_folding ¤Ï "simple-case-folding" - ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢Ê¸»ú¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤Æ»È¤ï¤ì¤ë¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£ - ¤ÎÃͤϡ¢Âбþ¤¹¤ë¾®Ê¸»ú°ìʸ»ú¤Ç¤¢¤ê¡¢Âçʸ»ú¡¿¾®Ê¸»ú¤Î¶èÊ̤ò̵»ë¤·¤¿ - ʸ»úÎóÈæ³Ó¤ÎºÝ¤Ë»È¤ï¤ì¤ë¡£ - - ¤â¤·¤½¤Î¤è¤¦¤ÊÈæ³Ó¤Ë»ÈÍѤ·ÆÀ¤ëñ°ì¤Î¾®Ê¸»ú¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç¡¢¤³¤Î¥× - ¥í¥Ñ¥Æ¥£¤ÎÃÍ¤Ï 0xFFFF ¤Ë¤Ê¤ë¡£¤³¤Î¾ì¹ç¤½¤Îʸ»ú¤Ï¡¢ - #Mcomplicated_case_folding ¤È¤¤¤¦¥­¡¼¤Îʸ»ú¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¡£ */ - -MSymbol Msimple_case_folding; -/***en - @brief Key for corresponding multiple lowercase characters - - The symbol #Mcomplicated_case_folding has the name - "complicated-case-folding" and is used as the key of a - character property. The value of such a property is the - corresponding M-text that contains a sequence of lowercase - characters to be used for comparing M-texts ignoring case. */ - -/***ja - @brief Âбþ¤¹¤ë¾®Ê¸»ú¤ÎÎó¤òɽ¤ï¤¹¥­¡¼ - - ¥·¥ó¥Ü¥ë #Mcomplicated_case_folding ¤Ï - "complicated-case-folding" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢Ê¸»ú¥×¥í¥Ñ¥Æ¥£ - ¤Î¥­¡¼¤È¤·¤Æ»È¤ï¤ì¤ë¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢Âбþ¤¹¤ë¾®Ê¸»úÎ󤫤é¤Ê - ¤ë M-text ¤Ç¤¢¤ê¡¢Âçʸ»ú¡¿¾®Ê¸»ú¤Î¶èÊ̤ò̵»ë¤·¤¿Ê¸»úÎóÈæ³Ó¤ÎºÝ¤Ë»È - ¤ï¤ì¤ë¡£ - */ - -MSymbol Mcomplicated_case_folding; -/*=*/ -/*** @} */ -/*=*/ - -/***en - @brief Define a character property. - - The mchar_define_property () function searches the m17n database - for a data whose tags are \<#Mchar_table, $TYPE, $SYM \>. - Here, $SYM is a symbol whose name is $NAME. $TYPE must be - #Mstring, #Mtext, #Msymbol, #Minteger, or #Mplist. - - @return - If the operation was successful, mchar_define_property () returns - $SYM. Otherwise it returns #Mnil. */ - -/***ja - @brief ʸ»ú¥×¥í¥Ñ¥Æ¥£¤òÄêµÁ¤¹¤ë - - ´Ø¿ô mchar_define_property () ¤Ï¡¢ \<#Mchar_table, $TYPE, $SYM \> - ¤È¤¤¤¦¥¿¥°¤ò»ý¤Ã¤¿¥Ç¡¼¥¿¥Ù¡¼¥¹¤ò m17n ¸À¸ì¾ðÊó¥Ù¡¼¥¹¤«¤éõ¤¹¡£ ¤³ - ¤³¤Ç $SYM ¤Ï $NAME ¤È¤¤¤¦Ì¾Á°¤Î¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£$TYPE ¤Ï#Mstring, - #Mtext, #Msymbol, #Minteger, #Mplist ¤Î¤¤¤º¤ì¤«¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ - - @return - ½èÍý¤ËÀ®¸ù¤¹¤ì¤Ð $SYM ¤òÊÖ¤¹¡£ - ¼ºÇÔ¤·¤¿¾ì¹ç¤Ï #Mnil ¤òÊÖ¤¹¡£ */ - -/*** - @errors - @c MERROR_DB - - @seealso - mchar_get_prop (), mchar_put_prop () */ - -MSymbol -mchar_define_property (char *name, MSymbol type) -{ - MSymbol key = msymbol (name); - MCharPropRecord *record; - - record = mplist_get (char_prop_list, key); - if (record) - { - if (record->table) - M17N_OBJECT_UNREF (record->table); - } - else - { - MSTRUCT_CALLOC (record, MERROR_CHAR); - mplist_put (char_prop_list, key, record); - } - - record->type = type; - if (mdatabase__finder - && (record->mdb = (*mdatabase__finder) (Mchar_table, type, key, Mnil))) - { - record->table = NULL; - } - else - { - void *default_value = NULL; - - record->mdb = NULL; - if (type == Minteger) - default_value = (void *) -1; - record->table = mchartable (type, default_value); - } - - return key; -} - -/*=*/ - -/***en - @brief Get the value of a character property. - - The mchar_get_prop () function searches character $C for the - character property whose key is $KEY. - - @return - If the operation was successful, mchar_get_prop () returns the - value of the character property. Otherwise it returns @c - NULL. */ - -/***ja - @brief ʸ»ú¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë - - ´Ø¿ô mchar_get_prop () ¤Ï¡¢Ê¸»ú $C ¤Îʸ»ú¥×¥í¥Ñ¥Æ¥£Ãæ¡¢¥­¡¼¤¬ $KEY - ¤Ç¤¢¤ë¤â¤Î¤òõ¤¹¡£ - - @return - ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mchar_get_prop () ¤Ï¸«¤Ä¤«¤Ã¤¿¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÊÖ - ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï #Mnil ¤òÊÖ¤¹¡£ - - @latexonly \IPAlabel{mchar_get_prop} @endlatexonly -*/ - -/*** - @errors - @c MERROR_SYMBOL, @c MERROR_DB - - @seealso - mchar_define_property (), mchar_put_prop () */ - -void * -mchar_get_prop (int c, MSymbol key) -{ - MCharPropRecord *record; - - record = mplist_get (char_prop_list, key); - if (! record) - return NULL; - if (record->mdb) - { - record->table = (*mdatabase__loader) (record->mdb); - if (! record->table) - MERROR (MERROR_DB, NULL); - record->mdb = NULL; - } - return mchartable_lookup (record->table, c); -} - -/*=*/ - -/***en - @brief Set the value of a character property. - - The mchar_put_prop () function searches character $C for the - character property whose key is $KEY and assigns $VAL to the value - of the found property. - - @return - If the operation was successful, mchar_put_prop () returns 0. - Otherwise, it returns -1. */ - -/***ja - @brief ʸ»ú¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÀßÄꤹ¤ë - - ´Ø¿ô mchar_put_prop () ¤Ïʸ»ú $C ¤Îʸ»ú¥×¥í¥Ñ¥Æ¥£Ãæ¡¢¥­¡¼¤¬ $KEY ¤Ç - ¤¢¤ë¤â¤Î¤òõ¤·¡¢¤½¤ÎÃͤȤ·¤Æ $VAL ¤òÀßÄꤹ¤ë¡£ - - @return - ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mchar_put_prop () ¤Ï0¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï-1¤òÊÖ - ¤¹¡£ */ - -/*** - @errors - @c MERROR_SYMBOL, @c MERROR_DB - - @seealso - mchar_define_property (), mchar_get_prop () */ - -int -mchar_put_prop (int c, MSymbol key, void *val) -{ - MCharPropRecord *record; - - record = mplist_get (char_prop_list, key); - if (! record) - return -1; - if (record->mdb) - { - record->table = (*mdatabase__loader) (record->mdb); - if (! record->table) - MERROR (MERROR_DB, -1); - M17N_OBJECT_REF (record->table); - record->mdb = NULL; - } - return mchartable_set (record->table, c, val); -} - -/*** @} */ - -/* - Local Variables: - coding: euc-japan - End: -*/ diff --git a/src/character.h b/src/character.h deleted file mode 100644 index 5a4638a..0000000 --- a/src/character.h +++ /dev/null @@ -1,283 +0,0 @@ -/* character.h -- header file for the character module. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -#ifndef _M17N_CHARACTER_H_ -#define _M17N_CHARACTER_H_ - -/* UTF-8 format - - 0-7F 0xxxxxxx - 80-7FF 110xxxxx 10xxxxxx - 800-FFFF 1110xxxx 10xxxxxx 10xxxxxx - 10000-1FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - 200000-3FFFFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx - 4000000-7FFFFFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx - - Unicode range: - 0-10FFFF 0 - 11110uuu 10uuxxxx 10xxxxxx 10xxxxxx (uuuuu <= 0x10) - -*/ - -#define MAX_UTF8_CHAR_BYTES 6 -#define MAX_UNICODE_CHAR_BYTES 4 - -/* Return how many units (char, short, or int) C will occupy in - MText->data. */ - -#define CHAR_UNITS_ASCII(c) ((c) < 0x80) - -#define CHAR_UNITS_UTF8(c) \ - ((c) < 0x80 ? 1 \ - : (c) < 0x800 ? 2 \ - : (c) < 0x10000 ? 3 \ - : (c) < 0x200000 ? 4 \ - : (c) < 0x4000000 ? 5 \ - : 6) - -#define CHAR_UNITS_UTF16(c) \ - ((c) < 0x10000 ? 1 \ - : (c) < 0x110000 ? 2 \ - : 0) - - -#define CHAR_UNITS_UTF32(c) 1 - -#define CHAR_UNITS(c, format) \ - ((c) < 0x80 ? 1 \ - : (format) == MTEXT_FORMAT_UTF8 ? CHAR_UNITS_UTF8 (c) \ - : (format) == MTEXT_FORMAT_UTF16 ? CHAR_UNITS_UTF16 (c) \ - : (format) == MTEXT_FORMAT_ASCII ? 0 \ - : CHAR_UNITS_UTF32 (c)) - -#define CHAR_BYTES CHAR_UNITS_UTF8 - -#define CHAR_UNITS_AT_UTF8(p) \ - (!(*(p) & 0x80) ? 1 \ - : !(*(p) & 0x20) ? 2 \ - : !(*(p) & 0x10) ? 3 \ - : !(*(p) & 0x08) ? 4 \ - : !(*(p) & 0x04) ? 5 \ - : !(*(p) & 0x02) ? 6 \ - : 0) - -#define CHAR_UNITS_AT_UTF16(p) \ - (2 - (*(unsigned short *) (p) < 0xD800 \ - || *(unsigned short *) (p) >= 0xDC00)) - -#define CHAR_UNITS_AT(c, format) \ - ((format) == MTEXT_FORMAT_UTF16 ? CHAR_UNITS_AT_UTF16 (c) \ - : (format) == MTEXT_FORMAT_UTF8 ? CHAR_UNITS_AT_UTF8 (c) \ - : 1) - -#define CHAR_BYTES_AT CHAR_UNITS_AT_UTF8 - -#define CHAR_UNITS_BY_HEAD_UTF8(c) \ - (!((c) & 0x80) ? 1 \ - : !((c) & 0x20) ? 2 \ - : !((c) & 0x10) ? 3 \ - : !((c) & 0x08) ? 4 \ - : !((c) & 0x04) ? 5 \ - : !((c) & 0x02) ? 6 \ - : 0) - -#define CHAR_UNITS_BY_HEAD_UTF16(c) \ - (2 - ((unsigned short) (c) < 0xD800 || (unsigned short) (c) >= 0xDC00)) - -#define CHAR_UNITS_BY_HEAD(c, format) \ - ((format) == MTEXT_FORMAT_UTF16 ? CHAR_UNITS_BY_HEAD_UTF16 (c) \ - : (format) == MTEXT_FORMAT_UTF8 ? CHAR_UNITS_BY_HEAD_UTF8 (c) \ - : 1) - -#define CHAR_BYTES_BY_HEAD CHAR_UNITS_BY_HEAD_UTF8 - -#define STRING_CHAR_UTF8(p) \ - (!((p)[0] & 0x80) ? (p)[0] \ - : !((p)[0] & 0x20) ? ((((p)[0] & 0x1F) << 6) \ - | ((p)[1] & 0x3F)) \ - : !((p)[0] & 0x10) ? ((((p)[0] & 0x0F) << 12) \ - | (((p)[1] & 0x3F) << 6) \ - | ((p)[2] & 0x3F)) \ - : !((p)[0] & 0x08) ? ((((p)[0] & 0x07) << 18) \ - | (((p)[1] & 0x3F) << 12) \ - | (((p)[2] & 0x3F) << 6) \ - | ((p)[3] & 0x3F)) \ - : !((p)[0] & 0x04) ? ((((p)[0] & 0x03) << 24) \ - | (((p)[1] & 0x3F) << 18) \ - | (((p)[2] & 0x3F) << 12) \ - | (((p)[3] & 0x3F) << 6) \ - | ((p)[4] & 0x3F)) \ - : ((((p)[0] & 0x01) << 30) \ - | (((p)[1] & 0x3F) << 24) \ - | (((p)[2] & 0x3F) << 18) \ - | (((p)[3] & 0x3F) << 12) \ - | (((p)[4] & 0x3F) << 6) \ - | ((p)[5] & 0x3F))) - -#define STRING_CHAR_UTF16(p) \ - (((unsigned short) (p)[0] < 0xD800 || (unsigned short) (p)[0] >= 0xDC00) \ - ? (p)[0] \ - : ((((p)[0] - 0xD800) << 10) + ((p)[1] - 0xDC00) + 0x10000)) - - -#define STRING_CHAR STRING_CHAR_UTF8 - - -#define STRING_CHAR_ADVANCE_UTF8(p) \ - (!(*(p) & 0x80) ? *(p)++ \ - : !(*(p) & 0x20) ? (((*(p)++ & 0x1F) << 6) \ - | (*(p)++ & 0x3F)) \ - : !(*(p) & 0x10) ? (((*(p)++ & 0x0F) << 12) \ - | ((*(p)++ & 0x3F) << 6) \ - | (*(p)++ & 0x3F)) \ - : !(*(p) & 0x08) ? (((*(p)++ & 0x07) << 18) \ - | ((*(p)++ & 0x3F) << 12) \ - | ((*(p)++ & 0x3F) << 6) \ - | (*(p)++ & 0x3F)) \ - : !(*(p) & 0x04) ? (((*(p)++ & 0x03) << 24) \ - | ((*(p)++ & 0x3F) << 18) \ - | ((*(p)++ & 0x3F) << 12) \ - | ((*(p)++ & 0x3F) << 6) \ - | (*(p)++ & 0x3F)) \ - : (((*(p)++ & 0x01) << 30) \ - | ((*(p)++ & 0x3F) << 24) \ - | ((*(p)++ & 0x3F) << 18) \ - | ((*(p)++ & 0x3F) << 12) \ - | ((*(p)++ & 0x3F) << 6) \ - | (*(p)++ & 0x3F))) - -#define STRING_CHAR_ADVANCE_UTF16(p) \ - (((unsigned short) (p)[0] < 0xD800 || (unsigned short) (p)[0] >= 0xDC00) \ - ? *(p)++ \ - : (((*(p)++ - 0xD800) << 10) + (*(p)++ - 0xDC00) + 0x10000)) - -#define STRING_CHAR_ADVANCE STRING_CHAR_ADVANCE_UTF8 - -#define STRING_CHAR_AND_UNITS_UTF8(p, bytes) \ - (!((p)[0] & 0x80) ? ((bytes) = 1, (p)[0]) \ - : !((p)[0] & 0x20) ? ((bytes) = 2, \ - ((((p)[0] & 0x1F) << 6) \ - | ((p)[1] & 0x3F))) \ - : !((p)[0] & 0x10) ? ((bytes) = 3, \ - ((((p)[0] & 0x0F) << 12) \ - | (((p)[1] & 0x3F) << 6) \ - | ((p)[2] & 0x3F))) \ - : !((p)[0] & 0x08) ? ((bytes) = 4, \ - ((((p)[0] & 0x07) << 18) \ - | (((p)[1] & 0x3F) << 12) \ - | (((p)[2] & 0x3F) << 6) \ - | ((p)[3] & 0x3F))) \ - : !((p)[0] & 0x04) ? ((bytes) = 5, \ - ((((p)[0] & 0x03) << 24) \ - | (((p)[1] & 0x3F) << 18) \ - | (((p)[2] & 0x3F) << 12) \ - | (((p)[3] & 0x3F) << 6) \ - | ((p)[4] & 0x3F))) \ - : ((bytes) = 6, \ - ((((p)[0] & 0x01) << 30) \ - | (((p)[1] & 0x3F) << 24) \ - | (((p)[2] & 0x3F) << 18) \ - | (((p)[3] & 0x3F) << 12) \ - | (((p)[4] & 0x3F) << 6) \ - | ((p)[5] & 0x3F)))) - -#define STRING_CHAR_AND_UNITS_UTF16(p, units) \ - (((unsigned short) (p)[0] < 0xD800 || (unsigned short) (p)[0] >= 0xDC00) \ - ? ((units) = 1, (p)[0]) \ - : ((units) = 2, \ - (((p)[0] - 0xD800) << 10) + ((p)[1] - 0xDC00) + 0x10000)) - -#define STRING_CHAR_AND_UNITS(p, units, format) \ - ((format) == MTEXT_FORMAT_UTF16 \ - ? STRING_CHAR_AND_UNITS_UTF16 (p, units) \ - : (format) == MTEXT_FORMAT_UTF8 \ - ? STRING_CHAR_AND_UNITS_UTF8 (p, units) \ - : ((units) = 1, (p)[0])) - - -#define STRING_CHAR_AND_BYTES STRING_CHAR_AND_UNITS_UTF8 - -#define CHAR_STRING_UTF8(c, p) \ - ((c) < 0x80 \ - ? ((p)[0] = (c), 1) \ - : (c) < 0x800 ? ((p)[0] = (0xC0 | ((c) >> 6)), \ - (p)[1] = (0x80 | ((c) & 0x3F)), \ - 2) \ - : (c) < 0x10000 ? ((p)[0] = (0xE0 | ((c) >> 12)), \ - (p)[1] = (0x80 | (((c) >> 6) & 0x3F)), \ - (p)[2] = (0x80 | ((c) & 0x3F)), \ - 3) \ - : (c) < 0x200000 ? ((p)[0] = (0xF0 | ((c) >> 18)), \ - (p)[1] = (0x80 | (((c) >> 12) & 0x3F)), \ - (p)[2] = (0x80 | (((c) >> 6) & 0x3F)), \ - (p)[3] = (0x80 | ((c) & 0x3F)), \ - 4) \ - : (c) < 0x4000000 ? ((p)[0] = 0xF8, \ - (p)[1] = (0x80 | ((c) >> 18)), \ - (p)[2] = (0x80 | (((c) >> 12) & 0x3F)), \ - (p)[3] = (0x80 | (((c) >> 6) & 0x3F)), \ - (p)[4] = (0x80 | ((c) & 0x3F)), \ - 5) \ - : ((p)[0] = (0xFC | ((c) >> 30)), \ - (p)[1] = (0x80 | (((c) >> 24) & 0x3F)), \ - (p)[2] = (0x80 | (((c) >> 18) & 0x3F)), \ - (p)[3] = (0x80 | (((c) >> 12) & 0x3F)), \ - (p)[4] = (0x80 | (((c) >> 6) & 0x3F)), \ - (p)[5] = (0x80 | ((c) & 0x3F)), \ - 6)) - -#define CHAR_STRING_UTF16(c, p) \ - ((c) < 0x10000 ? (p)[0] = (c), 1 \ - ? (p[0] = (((c) - 0x10000) >> 10) + 0xD800, \ - p[1] = (((c) - 0x10000) & 0x3FF) + 0xDC00, \ - 2)) - -#define CHAR_STRING CHAR_STRING_UTF8 - -#define CHAR_HEAD_P_UTF8(p) \ - ((*(p) & 0xC0) != 0x80) - -#define CHAR_HEAD_P_UTF16(p) \ - (*(unsigned short *) (p) < 0xDC00 \ - || *(unsigned short *) (p) >= 0xE000) - -#define CHAR_HEAD_P CHAR_HEAD_P_UTF8 - -/** Locale-safe version of tolower (). It works only for an ASCII - character. */ -#define TOLOWER(c) (((c) >= 'A' && (c) <= 'Z') ? (c) + 32 : (c)) - -/** Locale-safe version of toupper (). It works only for an ASCII - character. */ -#define TOUPPER(c) (((c) >= 'a' && (c) <= 'z') ? (c) - 32 : (c)) - -/** Locale-safe version of isupper (). It works only for an ASCII - character. */ -#define ISUPPER(c) ((c) >= 'A' && (c) <= 'Z') - -/** Locale-safe version of isalnum (). It works only for an ASCII - character. */ -#define ISALNUM(c) \ - (((c) >= 'A' && (c) <= 'Z') \ - || ((c) >= 'a' && (c) <= 'z') \ - || ((c) >= '0' && (c) <= '9')) - -#endif /* not _M17N_CHARACTER_H_ */ diff --git a/src/charset.c b/src/charset.c deleted file mode 100644 index a2d5755..0000000 --- a/src/charset.c +++ /dev/null @@ -1,1455 +0,0 @@ -/* charset.c -- charset module. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -/***en - @addtogroup m17nCharset - @brief Charset objects and API for them. - - The m17n library uses @e charset objects to represent a coded - character sets (CCS). The m17n library supports many predefined - coded character sets. Moreover, application programs can add - other charsets. A character can belong to multiple charsets. - - The m17n library distinguishes the following three concepts: - - @li A @e code-point is a number assigned by the CCS to each - character. Code-points may or may not be continuous. The type - @c unsigned is used to represent a code-point. An invalid - code-point is represented by the macro @c MCHAR_INVALID_CODE. - - @li A @e character @e index is the canonical index of a character - in a CCS. The character that has the character index N occupies - the Nth position when all the characters in the current CCS are - sorted by their code-points. Character indices in a CCS are - continuous and start with 0. - - @li A @e character @e code is the internal representation in the - m17n library of a character. A character code is a signed integer - of 21 bits or longer. - - Each charset object defines how characters are converted between - code-points and character codes. To @e encode means converting - code-points to character codes and to @e decode means converting - character codes to code-points. */ - -/***ja - @addtogroup m17nCharset - @brief ʸ»ú¥»¥Ã¥È¥ª¥Ö¥¸¥§¥¯¥È¤È¤½¤ì¤Ë´Ø¤¹¤ë API - - m17n ¥é¥¤¥Ö¥é¥ê¤Ï¡¢Éä¹æ²½Ê¸»ú½¸¹ç (CCS) ¤ò @e ʸ»ú¥»¥Ã¥È ¤È¸Æ¤Ö¥ª - ¥Ö¥¸¥§¥¯¥È¤Çɽ¸½¤¹¤ë¡£m17n ¥é¥¤¥Ö¥é¥ê¤Ï¿¤¯¤ÎÉä¹æ²½Ê¸»ú½¸¹ç¤òͽ¤á - ¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¤¬¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤¬Æȼ«¤Ëʸ»ú¥»¥Ã¥È¤ò - Äɲ乤뤳¤È¤â²Äǽ¤Ç¤¢¤ë¡£°ì¤Ä¤Îʸ»ú¤ÏÊ£¿ô¤Îʸ»ú¥»¥Ã¥È¤Ë°¤·¤Æ¤â¤è - ¤¤¡£ - - m17n ¥é¥¤¥Ö¥é¥ê¤Ë¤Ï¡¢°Ê²¼¤Î°Û¤Ê¤ë³µÇ°¤¬¤¢¤ë: - - @li @e ¥³¡¼¥É¥Ý¥¤¥ó¥È ¤È¤Ï¡¢CCS ¤¬¤½¤ÎÃæ¤Î¸Ä¡¹¤Îʸ»ú¤ËÂФ·¤ÆÄêµÁ¤¹ - ¤ë¿ôÃͤǤ¢¤ë¡£¥³¡¼¥É¥Ý¥¤¥ó¥È¤ÏϢ³¤·¤Æ¤¤¤ë¤È¤Ï¸Â¤é¤Ê¤¤¡£ - - @li @e ʸ»ú¥¤¥ó¥Ç¥Ã¥¯¥¹ ¤È¤Ï¡¢CCS Æâ¤Ç³Æʸ»ú¤Ë³ä¤êÅö¤Æ¤é¤ì¤ëÀµµ¬²½¤µ - ¤ì¤¿¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ç¤¢¤ë¡£Ê¸»ú¥¤¥ó¥Ç¥Ã¥¯¥¹¤¬N¤Îʸ»ú¤Ï¡¢CCS Ãæ¤ÎÁ´Ê¸»ú¤ò - ¥³¡¼¥É¥Ý¥¤¥ó¥È¤Ç¥½¡¼¥È¤·¤¿¤È¤­¤ËNÈÖÌܤËÍè¤ë¡£ - - @li @e ʸ»ú¥³¡¼¥É¤È¤Ï¡¢m17n ¥é¥¤¥Ö¥é¥êÆâ¤Ë¤ª¤±¤ëʸ»ú¤ÎÆâÉôɽ¸½¤Ç¤¢ - ¤ê¡¢21 ¥Ó¥Ã¥È°Ê¾å¤ÎŤµ¤ò»ý¤ÄÉä¹çÉÕ¤­À°¿ô¤Ç¤¢¤ë¡£ - - ³Æʸ»ú¥»¥Ã¥È¥ª¥Ö¥¸¥§¥¯¥È¤Ï¡¢¤½¤ì¤Ë°¤¹¤ëʸ»ú¤Î¥³¡¼¥É¥Ý¥¤¥ó¥È¤Èʸ»ú - ¥³¡¼¥É¤È¤ÎÁê¸ßÊÑ´¹¤òµ¬Äꤹ¤ë¡£¥³¡¼¥É¥Ý¥¤¥ó¥È¤«¤éʸ»ú¥³¡¼¥É¤Ø¤ÎÊÑ´¹ - ¤ò @e ¥Ç¥³¡¼¥É ¤È¸Æ¤Ó¡¢Ê¸»ú¥³¡¼¥É¤«¤é¥³¡¼¥É¥Ý¥¤¥ó¥È¤Ø¤ÎÊÑ´¹¤ò @e - ¥¨¥ó¥³¡¼¥É ¤È¸Æ¤Ö¡£ */ - -/*=*/ -#if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE) -/*** @addtogroup m17nInternal - @{ */ - -#include -#include -#include -#include -#include - -#include "m17n.h" -#include "m17n-misc.h" -#include "internal.h" -#include "symbol.h" -#include "charset.h" -#include "coding.h" -#include "chartab.h" -#include "plist.h" - -static int unified_max = MCHAR_MAX; - -/** List of all charsets ever defined. */ - -struct MCharsetList -{ - int size, inc, used; - MCharset **charsets; -}; - -static struct MCharsetList charset_list; - -static MPlist *charset_definition_list; - -/** Make a charset object from the template of MCharset structure - CHARSET, and return a pointer to the new charset object. - CHARSET->code_range[4N + 2] and TMPL->code_range[4N + 3] are not - yet set. */ - -static MCharset * -make_charset (MCharset *charset) -{ - unsigned min_code, max_code; - int i, n; - int *range = charset->code_range; - - if (charset->dimension < 1 || charset->dimension > 4) - MERROR (MERROR_CHARSET, NULL); - if ((charset->final_byte > 0 && charset->final_byte < '0') - || charset->final_byte > 127) - MERROR (MERROR_CHARSET, NULL); - - for (i = 0, n = 1; i < 4; i++) - { - if (range[i * 4] > range[i * 4 + 1]) - MERROR (MERROR_CHARSET, NULL); - range[i * 4 + 2] = range[i * 4 + 1] - range[i * 4] + 1; - n *= range[i * 4 + 2]; - range[i * 4 + 3] = n; - } - - min_code = range[0] | (range[4] << 8) | (range[8] << 16) | (range[12] << 24); - if (charset->min_code == 0) - charset->min_code = min_code; - else if (charset->min_code < min_code) - MERROR (MERROR_CHARSET, NULL); - max_code = range[1] | (range[5] << 8) | (range[9] << 16) | (range[13] << 24); - if (charset->max_code == 0) - charset->max_code = max_code; - else if (charset->max_code > max_code) - MERROR (MERROR_CHARSET, NULL); - - charset->code_range_min_code = min_code; - - if (charset->method == Msubset) - { - MCharset *parent; - - if (charset->nparents != 1) - MERROR (MERROR_CHARSET, NULL); - parent = charset->parents[0]; - if (parent->method == Msuperset - || charset->min_code - charset->subset_offset < parent->min_code - || charset->max_code - charset->subset_offset > parent->max_code) - MERROR (MERROR_CHARSET, NULL); - if (parent->method == Moffset) - { - unsigned code; - - code = charset->min_code - charset->subset_offset; - charset->min_char = DECODE_CHAR (parent, code); - code = charset->max_code - charset->subset_offset; - charset->max_char = DECODE_CHAR (parent, code); - } - else - { - unsigned min_code = charset->min_code - charset->subset_offset; - unsigned max_code = charset->max_code - charset->subset_offset; - int min_char = DECODE_CHAR (parent, min_code); - int max_char = min_char; - - for (++min_code; min_code <= max_code; min_code++) - { - int c = DECODE_CHAR (parent, min_code); - - if (c >= 0) - { - if (c < min_char) - min_char = c; - else if (c > max_char) - max_char = c; - } - } - charset->min_char = min_char; - charset->max_char = max_char; - } - charset->simple = 0; - } - else if (charset->method == Msuperset) - { - int min_char = 0, max_char = 0; - - if (charset->nparents < 2) - MERROR (MERROR_CHARSET, NULL); - for (i = 0; i < charset->nparents; i++) - if (charset->min_code > charset->parents[i]->min_code - || charset->max_code < charset->parents[i]->max_code) - MERROR (MERROR_CHARSET, NULL); - - for (i = 0; i < charset->nparents; i++) - { - MCharset *parent = charset->parents[i]; - - if (charset->min_code > parent->min_code - || charset->max_code < parent->max_code) - MERROR (MERROR_CHARSET, NULL); - if (i == 0) - min_char = parent->min_char, max_char = parent->max_char; - else if (parent->min_char < min_char) - min_char = parent->min_char; - else if (parent->max_char > max_char) - max_char = parent->max_char; - } - charset->min_char = min_char; - charset->max_char = max_char; - charset->simple = 0; - } - else - { - charset->no_code_gap - = (charset->dimension == 1 - || (range[2] == 256 - && (charset->dimension == 2 - || (range[6] == 256 - && (charset->dimension == 3 - || range[10] == 256))))); - - if (! charset->no_code_gap) - { - int j; - - memset (charset->code_range_mask, 0, - sizeof charset->code_range_mask); - for (i = 0; i < 4; i++) - for (j = range[i * 4]; j <= range[i * 4 + 1]; j++) - charset->code_range_mask[j] |= (1 << i); - } - - if (charset->method == Moffset) - { - charset->max_char = charset->min_char + range[15] - 1; - if (charset->min_char < 0 - || charset->max_char < 0 || charset->max_char > unified_max) - MERROR (MERROR_CHARSET, NULL); - charset->simple = charset->no_code_gap; - } - else if (charset->method == Mmap || charset->method == Munify) - { - MDatabase *mdb = mdatabase_find (Mcharset, charset->name, - Mnil, Mnil); - MPlist *plist; - - charset->simple = 0; - if (charset->method == Munify) - { - /* The magic number 12 below is to align to the - SUB_BITS_2 (defined in chartab.c) boundary in a - char-table. */ - unified_max -= ((range[15] >> 12) + 1) << 12; - charset->unified_max = unified_max; - } - - if (! mdb || ! (plist = mdatabase_load (mdb))) - MERROR (MERROR_CHARSET, NULL); - charset->decoder = mplist_value (plist); - charset->encoder = mplist_value (mplist_next (plist)); - M17N_OBJECT_UNREF (plist); - mchartable_range (charset->encoder, - &charset->min_char, &charset->max_char); - if (charset->method == Mmap) - charset->simple = charset->no_code_gap; - else - charset->max_char - = charset->unified_max + 1 + charset->code_range[15]; - } - else - MERROR (MERROR_CHARSET, NULL); - } - - MLIST_APPEND1 (&charset_list, charsets, charset, MERROR_CHARSET); - - if (charset->final_byte > 0) - { - MLIST_APPEND1 (&mcharset__iso_2022_table, charsets, charset, - MERROR_CHARSET); - if (charset->revision <= 0) - { - int chars = range[2]; - - if (chars == 128) /* ASCII case */ - chars = 94; - else if (chars == 256) /* ISO-8859-X case */ - chars = 96; - MCHARSET_ISO_2022 (charset->dimension, chars, charset->final_byte) - = charset; - } - } - - charset->fully_loaded = 1; - return charset; -} - -static int -load_charset_fully (MCharset *charset) -{ - if (charset->method == Msubset) - { - MCharset *parent = charset->parents[0]; - - if (! parent->fully_loaded - && load_charset_fully (parent) < 0) - MERROR (MERROR_CHARSET, -1); - if (parent->method == Moffset) - { - unsigned code; - - code = charset->min_code - charset->subset_offset; - charset->min_char = DECODE_CHAR (parent, code); - code = charset->max_code - charset->subset_offset; - charset->max_char = DECODE_CHAR (parent, code); - } - else - { - unsigned min_code = charset->min_code - charset->subset_offset; - unsigned max_code = charset->max_code - charset->subset_offset; - int min_char = DECODE_CHAR (parent, min_code); - int max_char = min_char; - - for (++min_code; min_code <= max_code; min_code++) - { - int c = DECODE_CHAR (parent, min_code); - - if (c >= 0) - { - if (c < min_char) - min_char = c; - else if (c > max_char) - max_char = c; - } - } - charset->min_char = min_char; - charset->max_char = max_char; - } - } - else if (charset->method == Msuperset) - { - int min_char = 0, max_char = 0; - int i; - - for (i = 0; i < charset->nparents; i++) - { - MCharset *parent = charset->parents[i]; - - if (! parent->fully_loaded - && load_charset_fully (parent) < 0) - MERROR (MERROR_CHARSET, -1); - if (i == 0) - min_char = parent->min_char, max_char = parent->max_char; - else if (parent->min_char < min_char) - min_char = parent->min_char; - else if (parent->max_char > max_char) - max_char = parent->max_char; - } - charset->min_char = min_char; - charset->max_char = max_char; - } - else /* charset->method is Mmap or Munify */ - { - MDatabase *mdb = mdatabase_find (Mcharset, charset->name, Mnil, Mnil); - MPlist *plist; - - if (! mdb || ! (plist = mdatabase_load (mdb))) - MERROR (MERROR_CHARSET, -1); - charset->decoder = mplist_value (plist); - charset->encoder = mplist_value (mplist_next (plist)); - M17N_OBJECT_UNREF (plist); - mchartable_range (charset->encoder, - &charset->min_char, &charset->max_char); - if (charset->method == Mmap) - charset->simple = charset->no_code_gap; - else - charset->max_char = charset->unified_max + 1 + charset->code_range[15]; - } - - charset->fully_loaded = 1; - return 0; -} - - -/* Internal API */ - -MPlist *mcharset__cache; - -/* Predefined charsets. */ -MCharset *mcharset__ascii; -MCharset *mcharset__binary; -MCharset *mcharset__m17n; -MCharset *mcharset__unicode; - -MCharsetISO2022Table mcharset__iso_2022_table; - -/** Initialize charset handler. */ - -int -mcharset__init () -{ - MPlist *param, *pl; - - mcharset__cache = mplist (); - mplist_set (mcharset__cache, Mt, NULL); - - MLIST_INIT1 (&charset_list, charsets, 128); - MLIST_INIT1 (&mcharset__iso_2022_table, charsets, 128); - charset_definition_list = mplist (); - - memset (mcharset__iso_2022_table.classified, 0, - sizeof (mcharset__iso_2022_table.classified)); - - Mcharset = msymbol ("charset"); - - Mmethod = msymbol ("method"); - Moffset = msymbol ("offset"); - Mmap = msymbol ("map"); - Munify = msymbol ("unify"); - Msubset = msymbol ("subset"); - Msuperset = msymbol ("superset"); - - Mdimension = msymbol ("dimension"); - Mmin_range = msymbol ("min-range"); - Mmax_range = msymbol ("max-range"); - Mmin_code = msymbol ("min-code"); - Mmax_code = msymbol ("max-code"); - Mascii_compatible = msymbol ("ascii-compatible"); - Mfinal_byte = msymbol ("final-byte"); - Mrevision = msymbol ("revision"); - Mmin_char = msymbol ("min-char"); - Mmapfile = msymbol_as_managing_key ("mapfile"); - Mparents = msymbol_as_managing_key ("parents"); - Msubset_offset = msymbol ("subset-offset"); - Mdefine_coding = msymbol ("define-coding"); - Maliases = msymbol_as_managing_key ("aliases"); - - param = mplist (); - pl = param; - /* Setup predefined charsets. */ - pl = mplist_add (pl, Mmethod, Moffset); - pl = mplist_add (pl, Mmin_range, (void *) 0); - pl = mplist_add (pl, Mmax_range, (void *) 0x7F); - pl = mplist_add (pl, Mascii_compatible, Mt); - pl = mplist_add (pl, Mfinal_byte, (void *) 'B'); - pl = mplist_add (pl, Mmin_char, (void *) 0); - Mcharset_ascii = mchar_define_charset ("ascii", param); - - mplist_put (param, Mmax_range, (void *) 0xFF); - mplist_put (param, Mfinal_byte, NULL); - Mcharset_iso_8859_1 = mchar_define_charset ("iso-8859-1", param); - - mplist_put (param, Mmax_range, (void *) 0x10FFFF); - Mcharset_unicode = mchar_define_charset ("unicode", param); - - mplist_put (param, Mmax_range, (void *) MCHAR_MAX); - Mcharset_m17n = mchar_define_charset ("m17n", param); - - mplist_put (param, Mmax_range, (void *) 0xFF); - Mcharset_binary = mchar_define_charset ("binary", param); - - M17N_OBJECT_UNREF (param); - - mcharset__ascii = MCHARSET (Mcharset_ascii); - mcharset__binary = MCHARSET (Mcharset_binary); - mcharset__m17n = MCHARSET (Mcharset_m17n); - mcharset__unicode = MCHARSET (Mcharset_unicode); - - return 0; -} - -void -mcharset__fini (void) -{ - int i; - MPlist *plist; - - for (i = 0; i < charset_list.used; i++) - { - MCharset *charset = charset_list.charsets[i]; - - if (charset->decoder) - free (charset->decoder); - if (charset->encoder) - M17N_OBJECT_UNREF (charset->encoder); - free (charset); - } - M17N_OBJECT_UNREF (mcharset__cache); - MLIST_FREE1 (&charset_list, charsets); - MLIST_FREE1 (&mcharset__iso_2022_table, charsets); - MPLIST_DO (plist, charset_definition_list) - M17N_OBJECT_UNREF (MPLIST_VAL (plist)); - M17N_OBJECT_UNREF (charset_definition_list); -} - - -MCharset * -mcharset__find (MSymbol name) -{ - MCharset *charset; - - charset = msymbol_get (name, Mcharset); - if (! charset) - { - MPlist *param = mplist_get (charset_definition_list, name); - - MPLIST_KEY (mcharset__cache) = Mt; - if (! param) - return NULL; - param = mplist__from_plist (param); - mchar_define_charset (MSYMBOL_NAME (name), param); - charset = msymbol_get (name, Mcharset); - M17N_OBJECT_UNREF (param); - } - MPLIST_KEY (mcharset__cache) = name; - MPLIST_VAL (mcharset__cache) = charset; - return charset; -} - - -/** Return the character corresponding to code-point CODE in CHARSET. - If CODE is invalid for CHARSET, return -1. */ - -int -mcharset__decode_char (MCharset *charset, unsigned code) -{ - int idx; - - if (code < 128 && charset->ascii_compatible) - return (int) code; - if (code < charset->min_code || code > charset->max_code) - return -1; - - if (! charset->fully_loaded - && load_charset_fully (charset) < 0) - MERROR (MERROR_CHARSET, -1); - - if (charset->method == Msubset) - { - MCharset *parent = charset->parents[0]; - - code -= charset->subset_offset; - return DECODE_CHAR (parent, code); - } - - if (charset->method == Msuperset) - { - int i; - - for (i = 0; i < charset->nparents; i++) - { - MCharset *parent = charset->parents[i]; - int c = DECODE_CHAR (parent, code); - - if (c >= 0) - return c; - } - return -1; - } - - idx = CODE_POINT_TO_INDEX (charset, code); - if (idx < 0) - return -1; - - if (charset->method == Mmap) - return charset->decoder[idx]; - - if (charset->method == Munify) - { - int c = charset->decoder[idx]; - - if (c < 0) - c = charset->unified_max + 1 + idx; - return c; - } - - /* Now charset->method should be Moffset. */ - return (charset->min_char + idx); -} - - -/** Return the code point of character C in CHARSET. If CHARSET does not - contain C, return MCHAR_INVALID_CODE. */ - -unsigned -mcharset__encode_char (MCharset *charset, int c) -{ - if (! charset->fully_loaded - && load_charset_fully (charset) < 0) - MERROR (MERROR_CHARSET, MCHAR_INVALID_CODE); - - if (charset->method == Msubset) - { - MCharset *parent = charset->parents[0]; - unsigned code = ENCODE_CHAR (parent, c); - - if (code == MCHAR_INVALID_CODE) - return code; - code += charset->subset_offset; - if (code >= charset->min_code && code <= charset->max_code) - return code; - return MCHAR_INVALID_CODE; - } - - if (charset->method == Msuperset) - { - int i; - - for (i = 0; i < charset->nparents; i++) - { - MCharset *parent = charset->parents[i]; - unsigned code = ENCODE_CHAR (parent, c); - - if (code != MCHAR_INVALID_CODE) - return code; - } - return MCHAR_INVALID_CODE; - } - - if (c < charset->min_char || c > charset->max_char) - return MCHAR_INVALID_CODE; - - if (charset->method == Mmap) - return (unsigned) mchartable_lookup (charset->encoder, c); - - if (charset->method == Munify) - { - if (c > charset->unified_max) - { - c -= charset->unified_max - 1; - return INDEX_TO_CODE_POINT (charset, c); - } - return (unsigned) mchartable_lookup (charset->encoder, c); - } - - /* Now charset->method should be Moffset */ - c -= charset->min_char; - return INDEX_TO_CODE_POINT (charset, c); -} - -int -mcharset__load_from_database () -{ - MDatabase *mdb = mdatabase_find (msymbol ("charset-list"), Mnil, Mnil, Mnil); - MPlist *def_list, *plist; - MPlist *definitions = charset_definition_list; - int mdebug_mask = MDEBUG_CHARSET; - - if (! mdb) - return 0; - MDEBUG_PUSH_TIME (); - def_list = (MPlist *) mdatabase_load (mdb); - MDEBUG_PRINT_TIME ("CHARSET", (stderr, " to load data.")); - MDEBUG_POP_TIME (); - if (! def_list) - return -1; - - MDEBUG_PUSH_TIME (); - MPLIST_DO (plist, def_list) - { - MPlist *pl; - MSymbol name; - - if (! MPLIST_PLIST_P (plist)) - MERROR (MERROR_CHARSET, -1); - pl = MPLIST_PLIST (plist); - if (! MPLIST_SYMBOL_P (pl)) - MERROR (MERROR_CHARSET, -1); - name = MPLIST_SYMBOL (pl); - pl = MPLIST_NEXT (pl); - definitions = mplist_add (definitions, name, pl); - M17N_OBJECT_REF (pl); - if ((pl = mplist_find_by_value (pl, Mdefine_coding)) - && (MSymbol) MPLIST_VAL (MPLIST_NEXT (pl)) == Mt) - mconv__register_charset_coding (name); - } - - M17N_OBJECT_UNREF (def_list); - MDEBUG_PRINT_TIME ("CHARSET", (stderr, " to parse the loaded data.")); - MDEBUG_POP_TIME (); - return 0; -} - -/*** @} */ -#endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */ - - -/* External API */ - -/*** @addtogroup m17nCharset */ -/*** @{ */ -/*=*/ - -#ifdef FOR_DOXYGEN -/***en - @brief Invalid code-point. - - The macro #MCHAR_INVALID_CODE gives the invalid code-point. */ - -/***ja - @brief ̵¸ú¤Ê¥³¡¼¥É¥Ý¥¤¥ó¥È - - ¥Þ¥¯¥í #MCHAR_INVALID_CODE ¤Ï̵¸ú¤Ê¥³¡¼¥É¥Ý¥¤¥ó¥È¤òÍ¿¤¨¤ë¡£ */ - -#define MCHAR_INVALID_CODE -#endif -/*=*/ -/***en - @brief The symbol @c Mcharset. - - Any decoded M-text has a text property whose key is the predefined - symbol @c Mcharset. The name of @c Mcharset is - "charset". */ - -/***ja - @brief ¥·¥ó¥Ü¥ë @c Mcharset - - ¥Ç¥³¡¼¥É¤µ¤ì¤¿ M-text ¤Ï¡¢¥­¡¼¤¬ @c Mcharset ¤Ç¤¢¤ë¤è¤¦¤Ê¥Æ¥­¥¹¥È - ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¡£¥·¥ó¥Ü¥ë @c Mcharset ¤Ï "charset" ¤È¤¤ - ¤¦Ì¾Á°¤Ç¤¢¤é¤«¤¸¤áÄêµÁ¤µ¤ì¤Æ¤¤¤ë¡£ */ - -MSymbol Mcharset; -/*=*/ - -/***en - @name Variables: Symbols representing a charset. - - Each of the following symbols represents a predefined charset. */ - -/***ja - @name ÊÑ¿ô: ʸ»ú¥»¥Ã¥È¤òɽ¤ï¤¹ÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë - - °Ê²¼¤Î³Æ¥·¥ó¥Ü¥ë¤Ï¡¢¥­¡¼¤¬ @c Mcharset ¤Ç¤¢¤ê¡¢Ãͤ¬Âбþ¤¹¤ëʸ»ú¥»¥Ã - ¥È¥ª¥Ö¥¸¥§¥¯¥È¡Ê @c MCharset ·¿¡Ë¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ - ¥Æ¥£¤ò»ý¤Ä¡£ */ -/*=*/ -/*** @{ */ -/*=*/ -/***en - @brief Symbol representing the charset ASCII. - - The symbol #Mcharset_ascii has name "ascii" and represents - the charset ISO 646, USA Version X3.4-1968 (ISO-IR-6). */ -/***ja - @brief ISO 646, USA Version ¤ËÂбþ¤¹¤ëʸ»ú¥»¥Ã¥È¤Î¥·¥ó¥Ü¥ë - - ¥·¥ó¥Ü¥ë #Mcharset_ascii ¤Ï "ascii" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢ - ISO 646, USA Version X3.4-1968 (ISO-IR-6) ¤ËÂбþ¤¹¤ëʸ»ú¥»¥Ã¥È¤ò»Ø - Äꤹ¤ë¤¿¤á¤Ë»È¤ï¤ì¤ë¡£ */ - -MSymbol Mcharset_ascii; - -/*=*/ -/***en - @brief Symbol representing the charset ISO/IEC 8859/1. - - The symbol #Mcharset_iso_8859_1 has name "iso-8859-1" - and represents the charset ISO/IEC 8859-1:1998. */ -/***ja - @brief ISO/IEC 8859-1:1998 ¤ËÂбþ¤¹¤ëʸ»ú¥»¥Ã¥È¤Î¥·¥ó¥Ü¥ë - - ¥·¥ó¥Ü¥ë #Mcharset_iso_8859_1 ¤Ï "iso-8859-1" ¤È¤¤¤¦Ì¾ - Á°¤ò»ý¤Á¡¢ISO/IEC 8859-1:1998 ¤ËÂбþ¤¹¤ëʸ»ú¥»¥Ã¥È¤ò»ØÄꤹ¤ë¤¿¤á¤Ë - »È¤ï¤ì¤ë¡£ */ - -MSymbol Mcharset_iso_8859_1; - -/***en - @brief Symbol representing the charset Unicode. - - The symbol #Mcharset_unicode has name "unicode" and - represents the charset Unicode. */ -/***ja - @brief Unicode ¤ËÂбþ¤¹¤ëʸ»ú¥»¥Ã¥È¤Î¥·¥ó¥Ü¥ë - - ¥·¥ó¥Ü¥ë #Mcharset_unicode ¤Ï "unicode" ¤È¤¤¤¦Ì¾Á°¤ò»ý - ¤Á¡¢Unicode ¤ËÂбþ¤¹¤ëʸ»ú¥»¥Ã¥È¤ò»ØÄꤹ¤ë¤¿¤á¤Ë»È¤ï¤ì¤ë¡£ */ - -MSymbol Mcharset_unicode; - -/*=*/ -/***en - @brief Symbol representing the largest charset. - - The symbol #Mcharset_m17n has name "m17n" and - represents the charset that contains all characters supported by - the m17n library. */ -/***ja - @brief Á´Ê¸»ú¤ò´Þ¤àʸ»ú¥»¥Ã¥È¤Î¥·¥ó¥Ü¥ë - - ¥·¥ó¥Ü¥ë #Mcharset_m17n ¤Ï "m17n" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢ - m17n ¥é¥¤¥Ö¥é¥ê¤¬°·¤¦Á´¤Æ¤Îʸ»ú¤ò´Þ¤àʸ»ú¥»¥Ã¥È¤ò»ØÄꤹ¤ë¤¿¤á¤Ë»È - ¤ï¤ì¤ë¡£ */ - -MSymbol Mcharset_m17n; - -/*=*/ -/***en - @brief Symbol representing the charset for ill-decoded characters. - - The symbol #Mcharset_binary has name "binary" and - represents the fake charset which the decoding functions put to an - M-text as a text property when they encounter an invalid byte - (sequence). See @ref m17nConv @latexonly - (P.\pageref{group__m17nConv}) @endlatexonly for more detail. */ - -MSymbol Mcharset_binary; - -/*=*/ -/*** @} */ -/*=*/ - -/***en - @name Variables: Parameter keys for mchar_define_charset (). - - These are the predefined symbols to use as parameter keys for the - function mchar_define_charset () (which see). */ - -/***ja - @name ÊÑ¿ô: mchar_define_charset ÍѤΥѥé¥á¡¼¥¿¡¦¥­¡¼ - - ¤³¤ì¤é¤Ï¡¢´Ø¿ô mchar_define_charset () ÍѤΥѥé¥á¡¼¥¿¡¦¥­¡¼¤È¤·¤Æ - »È¤ï¤ì¤ë¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£ ¾Ü¤·¤¯¤Ï¤³¤Î´Ø¿ô¤Î²òÀâ¤ò»²¾È¤Î¤³¤È¡£*/ -/*** @{ */ -/*=*/ - -/***en - Parameter key for mchar_define_charset () (which see). */ - -MSymbol Mmethod; -MSymbol Mdimension; -MSymbol Mmin_range; -MSymbol Mmax_range; -MSymbol Mmin_code; -MSymbol Mmax_code; -MSymbol Mascii_compatible; -MSymbol Mfinal_byte; -MSymbol Mrevision; -MSymbol Mmin_char; -MSymbol Mmapfile; -MSymbol Mparents; -MSymbol Msubset_offset; -MSymbol Mdefine_coding; -MSymbol Maliases; -/*=*/ -/*** @} */ -/*=*/ - -/***en - @name Variables: Symbols representing charset methods. - - These are the predefined symbols that can be a value of the - #Mmethod parameter of a charset used in an argument to the - mchar_define_charset () function. - - A method specifies how code-points and character codes are - converted. See the documentation of the mchar_define_charset () - function for the details. */ - -/***ja - @name ÊÑ¿ô: ʸ»ú¥»¥Ã¥È¤Î¥á¥½¥Ã¥É»ØÄê¤Ë»È¤ï¤ì¤ë¥·¥ó¥Ü¥ë - - ¤³¤ì¤é¤Ï¡¢Ê¸»ú¥»¥Ã¥È¤Î @e ¥á¥½¥Ã¥É ¤ò»ØÄꤹ¤ë¤¿¤á¤Î¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢ - ´Ø¿ô mchar_define_charset () ¤Î°ú¿ô¤È¤·¤Æ»È¤ï¤ì¤ë¡£ - - ¥á¥½¥Ã¥É¤È¤Ï¡¢¥³¡¼¥É¥Ý¥¤¥ó¥È¤Èʸ»ú¥³¡¼¥É¤òÁê¸ßÊÑ´¹¤¹¤ëºÝ¤ÎÊý¼°¤Î¤³ - ¤È¤Ç¤¢¤ë¡£¾Ü¤·¤¯¤Ï´Ø¿ô mchar_define_charset () ¤Î²òÀâ¤ò»²¾È¤Î¤³¤È¡£ */ -/*** @{ */ -/*=*/ -/***en - @brief Symbol for the offset type method of charset. - - The symbol #Moffset has the name "offset" and, when used - as a value of #Mmethod parameter of a charset, it means that the - conversion of code-points and character codes of the charset is - done by this calculation: - -@verbatim -CHARACTER-CODE = CODE-POINT - MIN-CODE + MIN-CHAR -@endverbatim - - where, MIN-CODE is a value of #Mmin_code parameter of the charset, - and MIN-CHAR is a value of #Mmin_char parameter. */ - -/***ja - @brief ¥ª¥Õ¥»¥Ã¥È·¿¤Î¥á¥½¥Ã¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë - - ¥·¥ó¥Ü¥ë #Moffset ¤Ï "offset" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢ - mchar_define_charset () ¤Ç¥ª¥Õ¥»¥Ã¥È·¿¤Î¥á¥½¥Ã¥É¤ò»ØÄꤹ¤ë¾ì¹ç¤Î°ú - ¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£*/ - -MSymbol Moffset; -/*=*/ - -/***en @brief Symbol for the map type method of charset. - - The symbol #Mmap has the name "map" and, when use as a - value of #Mmethod parameter of a charset, it means that the - conversion of code-points and character codes of the charset is - done by map looking up. The map must be given by #Mmapfile - parameter. */ - -/***ja @brief ¥Þ¥Ã¥×·¿¤Î¥á¥½¥Ã¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë - - ¥·¥ó¥Ü¥ë #Mmap ¤Ï "map" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢ - mchar_define_charset () ¤Ç¥Þ¥Ã¥×·¿¤Î¥á¥½¥Ã¥É¤ò»ØÄꤹ¤ë¾ì¹ç¤Î°ú¿ô¤È - ¤·¤ÆÍѤ¤¤é¤ì¤ë¡£*/ - -MSymbol Mmap; -/*=*/ - -/***en @brief Symbol for the unify type method of charset. - - The symbol #Munify has the name "unify" and, when used as - a value of #Mmethod parameter of a charset, it means that the - conversion of code-points and character codes of the charset is - done by map looking up and offsetting. The map must be given by - #Mmapfile parameter. For this kind of charset, a unique - consequent character code space for all characters is assigned. - If the map has an entry for a code-point, the conversion is done - by looking up the map. Otherwise, the conversion is done by this - calculation: - -@verbatim -CHARACTER-CODE = CODE-POINT - MIN-CODE + LOWEST-CHAR-CODE -@endverbatim - - where, MIN-CODE is a value of #Mmin_code parameter of the charset, - and LOWEST-CHAR-CODE is the lowest character code of the assigned - code space. */ - -/***ja @brief Áê³·¿¤Î¥á¥½¥Ã¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë - - ¥·¥ó¥Ü¥ë #Minherit ¤Ï "inherit" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢ - mchar_define_charset () ¤ÇÁê³·¿¤Î¥á¥½¥Ã¥É¤ò»ØÄꤹ¤ë¾ì¹ç¤Î°ú¿ô¤È¤· - ¤ÆÍѤ¤¤é¤ì¤ë¡£*/ - -MSymbol Munify; -/*=*/ - -/***en - @brief Symbol for the subset type method of charset. - - The symbol #Msubset has the name "subset" and, when used - as a value of #Mmethod parameter of a charset, it means that the - charset is a subset of a parent charset. The parent charset must - be given by #Mparents parameter. The conversion of code-points - and character codes of the charset is done conceptually by this - calculation: - -@verbatim -CHARACTER-CODE = PARENT-CODE (CODE-POINT) + SUBSET-OFFSET -@endverbatim - - where, PARENT-CODE is a pseudo function that returns a character - code of CODE-POINT in the parent charset, and SUBSET-OFFSET is a - value given by #Msubset_offset parameter. */ - -MSymbol Msubset; -/*=*/ - -/***en - @brief Symbol for the superset type method of charset. - - The symbol #Msuperset has the name "superset" and, when - used as a value of #Mmethod parameter of a charset, it means that - the charset is a superset of parent charsets. The parent charsets - must be given by #Mparents parameter. */ - -MSymbol Msuperset; -/*=*/ -/*** @} */ - -/***en - @brief Define a charset. - - The mchar_define_charset () function defines a new charset and - makes it accessible via a symbol whose name is $NAME. $PLIST - specifies parameters of the charset as below: - -
    - -
  • Key is #Mmethod, value is a symbol. - - The value specifies the method for decoding/encoding code-points - in the charset. It must be #Moffset, #Mmap (default), #Munify, - #Msubset, or #Msuperset. - -
  • Key is #Mdimension, value is an integer - - The value specifies the dimension of code-points of the charset. - It must be 1 (default), 2, 3, or 4. - -
  • Key is #Mmin_range, value is an unsigned integer - - The value specifies the minimum range of a code-point, which means - that the Nth byte of the value is the minimum Nth byte of - code-points of the charset. The default value is 0. - -
  • Key is #Mmax_range, value is an unsigned integer - - The value specifies the maximum range of a code-point, which means - that the Nth byte of the value is the maximum Nth byte of - code-points of the charset. The default value is 0xFF, 0xFFFF, - 0xFFFFFF, or 0xFFFFFFFF if the dimension is 1, 2, 3, or 4 - respectively. - -
  • Key is #Mmin_code, value is an unsigned integer - - The value specifies the minimum code-point of - the charset. The default value is the minimum range. - -
  • Key is #Mmax_code, value is an unsigned integer - - The value specifies the maximum code-point of - the charset. The default value is the maximum range. - -
  • Key is #Mascii_compatible, value is a symbol - - The value specifies whether the charset is ASCII compatible or - not. If the value is #Mnil (default), it is not ASCII - compatible, else compatible. - -
  • Key is #Mfinal_byte, value is an integer - - The value specifies the @e final @e byte of the charset registered - in The International Registry. It must be 0 (default) or 32..127. - The value 0 means that the charset is not in the registry. - -
  • Key is #Mrevision, value is an integer - - The value specifies the @e revision @e number of the charset - registered in The International Registry. it must be 0..127. If - the charset is not in The International Registry, the value is - ignored. The value 0 means that the charset has no revision - number. - -
  • Key is #Mmin_char, value is an integer - - The value specifies the minimum character code of the charset. - The default value is 0. - -
  • Key is #Mmapfile, value is an M-text - - If the method is #Mmap or #Munify, a data that contains - mapping information is added to the m17n database by calling - mdatabase_define () with the value as an argument $EXTRA_INFO, - i.e. the value is used as a file name of the data. - - Otherwise, this parameter is ignored. - -
  • Key is #Mparents, value is a plist - - If the method is #Msubset, the value must is a plist of length - 1, and the value of the plist must be a symbol representing a - parent charset. - - If the method is #Msuperset, the value must be a plist of length - less than 9, and the values of the plist must be symbols - representing subset charsets. - - Otherwise, this parameter is ignored. - -
  • Key is #Mdefine_coding, value is a symbol - - If the dimension of the charset is 1, the value specifies whether - or not to define a coding system of the same name whose method is - @c charset. - - Otherwise, this parameter is ignored. - -
- - @return - If the operation was successful, mchar_define_charset () returns a - symbol whose name is $NAME. Otherwise it returns #Mnil and - assigns an error code to the external variable #merror_code. */ - -/***ja - @brief ʸ»ú¥»¥Ã¥È¤òÄêµÁ¤¹¤ë. - - ´Ø¿ô mchar_define_charset () ¤Ï¿·¤·¤¤Ê¸»ú¥»¥Ã¥È¤òÄêµÁ¤·¡¢¤½¤ì¤ò - $NAME ¤È¤¤¤¦Ì¾Á°¤Î¥·¥ó¥Ü¥ë·Ðͳ¤Ç¥¢¥¯¥»¥¹¤Ç¤­¤ë¤è¤¦¤Ë¤¹¤ë¡£$METHOD - ¤Ï¤½¤Îʸ»ú¥»¥Ã¥È¤Ë¤ª¤±¤ë¥³¡¼¥É¥Ý¥¤¥ó¥È¤Î¥Ç¥³¡¼¥É¡¿¥¨¥ó¥³¡¼¥É¥á¥½¥Ã - ¥É¤ò»ØÄꤹ¤ë¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢#Moffset, #Mmap, #Munify, - #Msubset, #Msuperset ¤Î¤¤¤º¤ì¤«¤ÎÃͤò¤È¤ë¡£ - - $DIMENSION ¤Ï¤½¤Îʸ»ú¥»¥Ã¥È¤Î¥³¡¼¥É¥Ý¥¤¥ó¥È¤Î¼¡¸µ¤Ç¤¢¤ê¡¢1, 2, 3, - 4¤Î¤¤¤º¤ì¤«¤ÎÃͤò¤È¤ë¡£ - - $CODE_RANGE ¤ÏÂ礭¤µ¤¬8¥Ð¥¤¥È¤ÎÇÛÎó¤Ç¤¢¤ê¡¢ÄêµÁ¤µ¤ì¤ëʸ»ú¥»¥Ã¥È¤Î - ¥³¡¼¥É¥Ý¥¤¥ó¥È¶õ´Ö¤òɽ¤ï¤¹¡£Âè1¥Ð¥¤¥È¤ÈÂè2¥Ð¥¤¥È¤ÎÃͤϥ³¡¼¥É¥Ý¥¤¥ó - ¥È¤ÎºÇ½é¤Î¼¡¸µ¤Ç¤ÎºÇ¾®¡¿ºÇÂç¥Ð¥¤¥È¤ÎÃͤǤ¢¤ë¡£Âè3¥Ð¥¤¥È¤ÈÂè4¥Ð¥¤¥È - ¤Ï¡¢2ÈÖÌܤμ¡¸µ¤ÎºÇ¾®¡¿ºÇÂçÃͤǤ¢¤ê¡¢ °Ê²¼Æ±Íͤ˳¤¯¡£°ìÈÌŪ¤Ë¡¢Âè - (2N-1)¥Ð¥¤¥È¤ÈÂè(2N)¥Ð¥¤¥È¤¬NÈÖÌܤμ¡¸µ¤ÎºÇ¾®¡¿ºÇÂçÃͤȤʤë (N = - 1, 2, 3, 4)¡£¥³¡¼¥É¥Ý¥¤¥ó¥È¤Î @e ʸ»ú¥¤¥ó¥Ç¥Ã¥¯¥¹ ¤Ï¤³¤ì¤é¤ÎÃͤ«¤é - ·×»»¤µ¤ì¤ë¡£ - - $MIN_CODE ¤È $MAX_CODE ¤Ï¡¢¤½¤ì¤¾¤ì¤³¤Îʸ»ú¥»¥Ã¥È¤ÎºÇ¾®¤ª¤è¤ÓºÇÂç - ¥³¡¼¥É¥Ý¥¤¥ó¥È¤òɽ¤ï¤¹¡£0¤¬»ØÄꤵ¤ì¤¿¾ì¹ç¤Ï $CODE_RANGE ¤ÎÃͤ«¤é·× - »»¤µ¤ì¤ë¡£ - - $FINAL_BYTE ¤Ï The International Registry ¤ËÅÐÏ¿¤µ¤ì¤Æ¤¤¤ë - @e ½ªÃ¼¥Ð¥¤¥È ¤Ç¤¢¤ë¡£ÅÐÏ¿¤µ¤ì¤Æ¤¤¤Ê¤¤ CCS ¤Î¾ì¹ç¤Ë¤Ï -1 ¤Ç¤Ê¤¯¤Æ¤Ï - ¤Ê¤é¤Ê¤¤¡£ - - $REVISION ¤Ï¡¢The International Registry ¤ËÅÐÏ¿¤µ¤ì¤Æ¤¤¤ë@e revision - @e number ¤Ç¤¢¤ë¡£¤â¤· revision number ¤¬Â¸ºß¤·¤Ê¤¤¤Ê¤é -1 ¤Ç¤Ê¤¯ - ¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ - - @par ¥á¥½¥Ã¥É¤¬ Moffset ¤Î¾ì¹ç - - $MIN_CHAR ¤Ë¤ÏºÇ¾®¤Î¥³¡¼¥É¥Ý¥¤¥ó¥È¤ËÂбþ¤¹¤ëʸ»ú¥³¡¼¥É¤òÍ¿¤¨¤ë¡£ - $NPARENTS, $PARENTS, ¤ª¤è¤Ó $SUBSET_OFFSET ¤Ï̵»ë¤µ¤ì¤ë¡£ - - @par ¥á¥½¥Ã¥É¤¬ Mmap ¤Î¾ì¹ç - - m17n ¸À¸ì¾ðÊó¥Ù¡¼¥¹Ãæ¤Ç \<#Mcharset, $NAME\> ¤È¤¤¤¦¥¿¥°¤ÎÉÕ¤¤¤¿ - ¥Þ¥Ã¥Ô¥ó¥°¥Æ¡¼¥Ö¥ë¤ò¡¢¥Ç¥³¡¼¥É¤ª¤è¤Ó¥¨¥ó¥³¡¼¥É¤ËÍѤ¤¤ë¡£$MIN_CHAR, - $NPARENTS, $PARENTS, ¤ª¤è¤Ó $SUBSET_OFFSET ¤Ï̵»ë¤µ¤ì¤ë¡£ - - @par ¥á¥½¥Ã¥É¤¬ Msubset ¤Î¾ì¹ç - - $NPARENTS ¤Ï1¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿ $PARENTS ¤Ï·Ñ¾µ¤Î¸µ¤È¤Ê¤ëʸ - »ú¥»¥Ã¥È¤òɽ¤ï¤¹¥·¥ó¥Ü¥ë¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¸µ¤Îʸ»ú¥»¥Ã¥È¤Î¥³¡¼¥É - ¥Ý¥¤¥ó¥È¤Ë $SUBSET_OFFSET ¤ò²Ã¤¨¤¿¤â¤Î¤¬¡¢¿·¤·¤¤Ê¸»ú¥»¥Ã¥ÈÃæ¤Ç¤Î¥³¡¼ - ¥É¥Ý¥¤¥ó¥È¤Ë¤Ê¤ë¡£$MIN_CHAR ¤Ï̵»ë¤µ¤ì¤ë¡£ - - @par ¥á¥½¥Ã¥É¤¬ Msuperset ¤Î¾ì¹ç - - $NPARENTS ¤Ï¿Æ¤È¤Ê¤ëʸ»ú¥»¥Ã¥È¤Î¿ô¡¢$PARENTS ¤Ï¿Æʸ»ú¥»¥Ã¥È¤Î¥·¥ó - ¥Ü¥ë¤ÎÇÛÎó¤òɽ¤ï¤¹¡£$MIN_CHAR ¤ª¤è¤Ó $SUBSET_OFFSET ¤Ï̵»ë¤µ¤ì¤ë¡£ - - @return - ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¡¢mchar_define_charset () ¤Ï $NAME ¤È¤¤¤¦Ì¾Á°¤Î¥· - ¥ó¥Ü¥ë¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð #Mnil ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô @c - merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ */ - -/*** - @errors - @c MERROR_CHARSET */ - -MSymbol -mchar_define_charset (char *name, MPlist *plist) -{ - MSymbol sym = msymbol (name); - MCharset *charset; - int i; - unsigned min_range, max_range; - MPlist *pl; - MText *mapfile = (MText *) mplist_get (plist, Mmapfile); - - MSTRUCT_CALLOC (charset, MERROR_CHARSET); - charset->name = sym; - charset->method = (MSymbol) mplist_get (plist, Mmethod); - if (! charset->method) - { - if (mapfile) - charset->method = Mmap; - else - charset->method = Moffset; - } - if (charset->method == Mmap || charset->method == Munify) - { - if (! mapfile) - MERROR (MERROR_CHARSET, Mnil); - mdatabase_define (Mcharset, sym, Mnil, Mnil, NULL, mapfile->data); - } - if (! (charset->dimension = (int) mplist_get (plist, Mdimension))) - charset->dimension = 1; - - min_range = (unsigned) mplist_get (plist, Mmin_range); - if ((pl = mplist_find_by_key (plist, Mmax_range))) - { - max_range = (unsigned) MPLIST_VAL (pl); - if (max_range >= 0x1000000) - charset->dimension = 4; - else if (max_range >= 0x10000 && charset->dimension < 3) - charset->dimension = 3; - else if (max_range >= 0x100 && charset->dimension < 2) - charset->dimension = 2; - } - else if (charset->dimension == 1) - max_range = 0xFF; - else if (charset->dimension == 2) - max_range = 0xFFFF; - else if (charset->dimension == 3) - max_range = 0xFFFFFF; - else - max_range = 0xFFFFFFFF; - - memset (charset->code_range, 0, sizeof charset->code_range); - for (i = 0; i < charset->dimension; i++, min_range >>= 8, max_range >>= 8) - { - charset->code_range[i * 4] = min_range & 0xFF; - charset->code_range[i * 4 + 1] = max_range & 0xFF; - } - if ((charset->min_code = (int) mplist_get (plist, Mmin_code)) < min_range) - charset->min_code = min_range; - if ((charset->max_code = (int) mplist_get (plist, Mmax_code)) > max_range) - charset->max_code = max_range; - charset->ascii_compatible - = (MSymbol) mplist_get (plist, Mascii_compatible) != Mnil; - charset->final_byte = (int) mplist_get (plist, Mfinal_byte); - charset->revision = (int) mplist_get (plist, Mrevision); - charset->min_char = (int) mplist_get (plist, Mmin_char); - pl = (MPlist *) mplist_get (plist, Mparents); - charset->nparents = pl ? mplist_length (pl) : 0; - if (charset->nparents > 8) - charset->nparents = 8; - for (i = 0; i < charset->nparents; i++, pl = MPLIST_NEXT (pl)) - { - MSymbol parent_name; - - if (MPLIST_KEY (pl) != Msymbol) - MERROR (MERROR_CHARSET, Mnil); - parent_name = MPLIST_SYMBOL (pl); - if (! (charset->parents[i] = MCHARSET (parent_name))) - MERROR (MERROR_CHARSET, Mnil); - } - - charset->subset_offset = (int) mplist_get (plist, Msubset_offset); - - msymbol_put (sym, Mcharset, charset); - charset = make_charset (charset); - if (! charset) - return Mnil; - msymbol_put (msymbol__canonicalize (sym), Mcharset, charset); - - for (pl = (MPlist *) mplist_get (plist, Maliases); - pl && MPLIST_KEY (pl) == Msymbol; - pl = MPLIST_NEXT (pl)) - { - MSymbol alias = MPLIST_SYMBOL (pl); - - msymbol_put (alias, Mcharset, charset); - msymbol_put (msymbol__canonicalize (alias), Mcharset, charset); - } - - if (mplist_get (plist, Mdefine_coding) - && charset->dimension == 1 - && charset->code_range[0] == 0 && charset->code_range[1] == 255) - mconv__register_charset_coding (sym); - return (sym); -} - -/*=*/ - -/***en - @brief Resolve charset name. - - The mchar_resolve_charset () function returns $SYMBOL if it - represents a charset. Otherwise, canonicalize $SYMBOL as to a - charset name, and if the canonicalized name represents a charset, - return it. Otherwise, return #Mnil. */ - -MSymbol -mchar_resolve_charset (MSymbol symbol) -{ - MCharset *charset = (MCharset *) msymbol_get (symbol, Mcharset); - - if (! charset) - { - symbol = msymbol__canonicalize (symbol); - charset = (MCharset *) msymbol_get (symbol, Mcharset); - } - - return (charset ? charset->name : Mnil); -} - -/*=*/ - -/***en - @brief List symbols representing a charset. - - The mchar_list_charsets () function makes an array of symbols - representing a charset, stores the pointer to the array in a place - pointed to by $SYMBOLS, and returns the length of the array. */ - -int -mchar_list_charset (MSymbol **symbols) -{ - int i; - - MTABLE_MALLOC ((*symbols), charset_list.used, MERROR_CHARSET); - for (i = 0; i < charset_list.used; i++) - (*symbols)[i] = charset_list.charsets[i]->name; - return i; -} - -/*=*/ - -/***en - @brief Decode a code-point. - - The mchar_decode () function decodes code-point $CODE in the - charset represented by the symbol $CHARSET_NAME to get a character - code. - - @return - If decoding was successful, mchar_decode () returns the decoded - character code. Otherwise it returns -1. */ - -/***ja - @brief ¥³¡¼¥É¥Ý¥¤¥ó¥È¤ò¥Ç¥³¡¼¥É¤¹¤ë - - ´Ø¿ô mchar_decode () ¤Ï¡¢¥·¥ó¥Ü¥ë $CHARSET_NAME ¤Ç¼¨¤µ¤ì¤ëʸ»ú¥»¥Ã - ¥ÈÆâ¤Î $CODE ¤È¤¤¤¦¥³¡¼¥É¥Ý¥¤¥ó¥È¤ò¥Ç¥³¡¼¥É¤·¤Æʸ»ú¥³¡¼¥É¤òÆÀ¤ë¡£ - - @return - ¥Ç¥³¡¼¥É¤¬À®¸ù¤¹¤ì¤Ð¡¢mchar_decode () ¤Ï¥Ç¥³¡¼¥É¤µ¤ì¤¿Ê¸»ú¥³¡¼¥É¤ò - ÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£ */ - -/*** - @seealso - mchar_encode () */ - -int -mchar_decode (MSymbol charset_name, unsigned code) -{ - MCharset *charset = MCHARSET (charset_name); - - if (! charset) - return MCHAR_INVALID_CODE; - return DECODE_CHAR (charset, code); -} - -/*=*/ - -/***en - @brief Encode a character code. - - The mchar_encode () function encodes character code $C to get a - code-point in the charset represented by the symbol $CHARSET_NAME. - - @return - If encoding was successful, mchar_encode () returns the encoded - code-point. Otherwise it returns #MCHAR_INVALID_CODE. */ - -/***ja - @brief ʸ»ú¥³¡¼¥É¤ò¥¨¥ó¥³¡¼¥É¤¹¤ë - - ´Ø¿ô mchar_encode () ¤Ï¡¢Ê¸»ú¥³¡¼¥É $C ¤ò¥¨¥ó¥³¡¼¥É¤·¤Æ¥·¥ó¥Ü¥ë - $CHARSET_NAME ¤Ç¼¨¤µ¤ì¤ëʸ»ú¥»¥Ã¥ÈÆâ¤Ë¤ª¤±¤ë¥³¡¼¥É¥Ý¥¤¥ó¥È¤òÆÀ¤ë¡£ - - @return - ¥¨¥ó¥³¡¼¥É¤¬À®¸ù¤¹¤ì¤Ð¡¢mchar_encode () ¤Ï¥¨¥ó¡¼¥É¤µ¤ì¤¿¥³¡¼¥É¥Ý¥¤ - ¥ó¥È¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð #MCHAR_INVALID_CODE ¤òÊÖ¤¹¡£ */ - -/*** - @seealso - mchar_decode () */ - -unsigned -mchar_encode (MSymbol charset_name, int c) -{ - MCharset *charset = MCHARSET (charset_name); - - if (! charset) - return MCHAR_INVALID_CODE; - return ENCODE_CHAR (charset, c); -} - -/*=*/ - -/***en - @brief Call a function for all the characters in a specified charset. - - The mcharset_map_chars () function calls $FUNC for all the - characters in the charset named $CHARSET_NAME. A call is done for - a chunk of consecutive characters rather than character by - character. - - $FUNC receives three arguments: $FROM, $TO, and $ARG. $FROM and - $TO specify the range of character codes in $CHARSET. $ARG is the - same as $FUNC_ARG. - - @return - If the operation was successful, mcharset_map_chars () returns 0. - Otherwise, it returns -1 and assigns an error code to the external - variable #merror_code. */ - -/***ja - @brief »ØÄꤷ¤¿Ê¸»ú¥»¥Ã¥È¤Î¤¹¤Ù¤Æ¤Îʸ»ú¤ËÂФ·¤Æ´Ø¿ô¤ò¸Æ¤Ö - - ´Ø¿ô mcharset_map_chars () ¤Ï $CHARSET_NAME ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Äʸ»ú¥»¥Ã - ¥ÈÃæ¤Î¤¹¤Ù¤Æ¤Îʸ»ú¤ËÂФ·¤Æ $FUNC ¤ò¸Æ¤Ö¡£¸Æ¤Ó½Ð¤·¤Ï°ìʸ»úËè¤Ç¤Ï¤Ê - ¤¯¡¢Ï¢Â³¤·¤¿Ê¸»ú¤Î¤Þ¤È¤Þ¤êñ°Ì¤Ç¹Ô¤Ê¤ï¤ì¤ë¡£ - - ´Ø¿ô $FUNC ¤Ë¤Ï$FROM, $TO, $ARG ¤Î£³°ú¿ô¤¬ÅϤµ¤ì¤ë¡£$FROM ¤È $TO - ¤Ï $CHARSET Ãæ¤Îʸ»ú¥³¡¼¥É¤ÎÈϰϤò»ØÄꤹ¤ë¡£$ARG ¤Ï $FUNC_ARG ¤ÈƱ - ¤¸¤Ç¤¢¤ë¡£ - - @return - ½èÍý¤ËÀ®¸ù¤¹¤ì¤Ð mcharset_map_chars () ¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð - -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ */ - -/*** - @errors - @c MERROR_CHARSET */ - -int -mchar_map_charset (MSymbol charset_name, - void (*func) (int from, int to, void *arg), - void *func_arg) -{ - MCharset *charset; - - charset = MCHARSET (charset_name); - if (! charset) - MERROR (MERROR_CHARSET, -1); - - if (charset->encoder) - { - int c = charset->min_char; - int next_c; - - if ((int) mchartable__lookup (charset->encoder, c, &next_c, 1) < 0) - c = next_c; - while (c <= charset->max_char) - { - if ((int) mchartable__lookup (charset->encoder, c, &next_c, 1) >= 0) - (*func) (c, next_c - 1, func_arg); - c = next_c; - } - } - else - (*func) (charset->min_char, charset->max_char, func_arg); - return 0; -} - -/*=*/ - -/*** @} */ - -/* - Local Variables: - coding: euc-japan - End: -*/ diff --git a/src/charset.h b/src/charset.h deleted file mode 100644 index 5b9e430..0000000 --- a/src/charset.h +++ /dev/null @@ -1,253 +0,0 @@ -/* charset.h -- header file for the charset module. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -#ifndef _M17N_CHARSET_H_ -#define _M17N_CHARSET_H_ - -/** @file charset.h - @brief Header for charset handlers. -*/ - -enum mcharset_method - { - MCHARSET_METHOD_OFFSET, - MCHARSET_METHOD_MAP, - MCHARSET_METHOD_DEFERRED, - MCHARSET_METHOD_SUBSET, - MCHARSET_METHOD_SUPERSET, - MCHARSET_METHOD_MAX - }; - -/** Structure for charset. */ - -typedef struct MCharset MCharset; - -struct MCharset -{ - /** The value is always 0 because all charsets are static. */ - unsigned ref_count; - - /** Symbol indicating the name of the charset. */ - MSymbol name; - - /** Number of dimensions of the charset. It must be 1, 2, 3, or - 4. */ - int dimension; - - /** Byte code range of each dimension. [4N] is a - minimum byte code of the (N+1)th dimension, [4N+1] - is a maximum byte code of the (N+1)th dimension, - [4N+2] is ([4N+1] - [4N] + - 1), [4N+3] is a number of characters contained in the - first to (N+1)th dimensions. We get "char-index" of a - "code-point" from this information. */ - int code_range[16]; - - /** The minimum code-point calculated from . It may be - smaller than . */ - int code_range_min_code; - - /** Nonzero means there is no gap in code points of the charset. If - is 1, is always 1. Otherwise, - is 1 iff [4N] is zero and - [4N+1] is 256 for N = 0..-2. If - is nonzero, "char-index" is "code-point" - - . */ - int no_code_gap; - - /** If the byte code B is valid in the (N+1)th dimension, - ([B] & (1 << N)) is 1. Otherwise, - ([B] & (1 << N)) is 0. */ - unsigned char code_range_mask[256]; - - /** Minimum and maximum code-point of the charset. */ - unsigned min_code, max_code; - - /** Nonzero means the charset encodes ASCII characters as is. */ - int ascii_compatible; - - /** Minimum and maximum character of the charset. If - is nonzero, is actually the - minimum non-ASCII character of the charset. */ - int min_char, max_char; - - /** ISO 2022 final byte of the charset. It must be in the range - 48..127, or -1. The value -1 means that the charset is not - encodable by ISO 2022 based coding systems. */ - int final_byte; - - /** ISO 2022 revision number of the charset, or -1. The value -1 - means that the charset has no revision number. Used only when - is not -1. */ - int revision; - - /** Specify how to encode/decode code-point of the charset. It must - be Moffset, Mmap, Munify, Msubset, or Msuperset. */ - MSymbol method; - - /** Array of integers to decode a code-point of the charset. It is - indexed by a "char-index" of the code-point, and the - corresponding element is a character of the charset, or -1 if - the code point is not valid in the charset. Used only when - is Mmap or Munify. */ - int *decoder; - - /** Char-table to encode a character of the charset. It is indexed - by a character code, and the corresponding element is a code - point of the character in the charset, or - MCHAR_INVALID_CODE if the character is not included in the - charset. Used only when is Mmap or Munify. */ - MCharTable *encoder; - - int unified_max; - - /** Array of pointers to parent charsets. Used only when - is Msubset or Msuperset. Atmost 8 parents are supported. */ - MCharset *parents[8]; - - /* Number of parent charsets. */ - int nparents; - - unsigned subset_min_code, subset_max_code; - int subset_offset; - - int simple; - - /** If the charset is fully loaded (i.e. all the above member are - set to correct values), the value is 1. Otherwise, the value is - 0. */ - int fully_loaded; -}; - -extern MPlist *mcharset__cache; - -/** Return a charset associated with the symbol CHARSET_SYM. */ - -#define MCHARSET(charset_sym) \ - (((charset_sym) == MPLIST_KEY (mcharset__cache) \ - || (MPLIST_KEY (mcharset__cache) = (charset_sym), \ - MPLIST_VAL (mcharset__cache) \ - = (MCharset *) msymbol_get ((charset_sym), Mcharset))) \ - ? MPLIST_VAL (mcharset__cache) \ - : mcharset__find (charset_sym)) - - -/** Return index of a character whose code-point in CHARSET is CODE. - If CODE is not valid, return -1. */ - -#define CODE_POINT_TO_INDEX(charset, code) \ - ((charset)->no_code_gap \ - ? (code) - (charset)->min_code \ - : (((charset)->code_range_mask[(code) >> 24] & 0x8) \ - && ((charset)->code_range_mask[((code) >> 16) & 0xFF] & 0x4) \ - && ((charset)->code_range_mask[((code) >> 8) & 0xFF] & 0x2) \ - && ((charset)->code_range_mask[(code) & 0xFF] & 0x1)) \ - ? (((((code) >> 24) - (charset)->code_range[12]) \ - * (charset)->code_range[11]) \ - + (((((code) >> 16) & 0xFF) - (charset)->code_range[8]) \ - * (charset)->code_range[7]) \ - + (((((code) >> 8) & 0xFF) - (charset)->code_range[4]) \ - * (charset)->code_range[3]) \ - + (((code) & 0xFF) - (charset)->code_range[0]) \ - - ((charset)->min_code - (charset)->code_range_min_code)) \ - : -1) - - -/* Return code-point of a character whose index is IDX. - The validness of IDX is not checked. IDX may be modified. */ - -#define INDEX_TO_CODE_POINT(charset, idx) \ - ((charset)->no_code_gap \ - ? (idx) + (charset)->min_code \ - : (idx += (charset)->min_code - (charset)->code_range_min_code, \ - (((charset)->code_range[0] + (idx) % (charset)->code_range[2]) \ - | (((charset)->code_range[4] \ - + ((idx) / (charset)->code_range[3] % (charset)->code_range[6])) \ - << 8) \ - | (((charset)->code_range[8] \ - + ((idx) / (charset)->code_range[7] % (charset)->code_range[10])) \ - << 16) \ - | (((charset)->code_range[12] + ((idx) / (charset)->code_range[11])) \ - << 24)))) - - -/** Return a character whose code-point in CHARSET is CODE. If CODE - is invalid, return -1. */ - -#define DECODE_CHAR(charset, code) \ - (((code) < 128 && (charset)->ascii_compatible) \ - ? (int) (code) \ - : ((code) < (charset)->min_code || (code) > (charset)->max_code) \ - ? -1 \ - : ! (charset)->simple \ - ? mcharset__decode_char ((charset), (code)) \ - : (charset)->method == Moffset \ - ? (code) - (charset)->min_code + (charset)->min_char \ - : (charset)->decoder[(code) - (charset)->min_code]) - - -/** Return a code-point in CHARSET for character C. If CHARSET - does not contain C, return MCHAR_INVALID_CODE. */ - -#define ENCODE_CHAR(charset, c) \ - (! (charset)->simple \ - ? mcharset__encode_char ((charset), (c)) \ - : ((c) < (charset)->min_char || (c) > (charset)->max_char) \ - ? MCHAR_INVALID_CODE \ - : (charset)->method == Moffset \ - ? (c) - (charset)->min_char + (charset)->min_code \ - : (unsigned) mchartable_lookup ((charset)->encoder, (c))) - - -extern MCharset *mcharset__ascii; -extern MCharset *mcharset__binary; -extern MCharset *mcharset__m17n; -extern MCharset *mcharset__unicode; - -#define ISO_MAX_DIMENSION 3 -#define ISO_MAX_CHARS 2 -#define ISO_MAX_FINAL 0x80 /* only 0x30..0xFF are used */ - -typedef struct -{ - /* Table of ISO-2022 charsets. */ - int size, inc, used; - MCharset **charsets; - - /** A 3-dimensional table indexed by "dimension", "chars", and - "final byte" of an ISO-2022 charset to get the correponding - charset. A charset that has a revision number is not stored in - this table. */ - MCharset *classified[ISO_MAX_DIMENSION][ISO_MAX_CHARS][ISO_MAX_FINAL]; -} MCharsetISO2022Table; - -extern MCharsetISO2022Table mcharset__iso_2022_table; - -#define MCHARSET_ISO_2022(dim, chars, final) \ - mcharset__iso_2022_table.classified[(dim) - 1][(chars) == 96][(final)] - -extern MCharset *mcharset__find (MSymbol name); -extern int mcharset__decode_char (MCharset *charset, unsigned code); -extern unsigned mcharset__encode_char (MCharset *charset, int c); -extern int mcharset__load_from_database (); - -#endif /* _M17N_CHARSET_H_ */ diff --git a/src/chartab.c b/src/chartab.c deleted file mode 100644 index a48f342..0000000 --- a/src/chartab.c +++ /dev/null @@ -1,970 +0,0 @@ -/* chartab.h -- character table module. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -/***en - @addtogroup m17nChartable - @brief Chartable objects and API for them. - - The m17n library supports enormous number of characters. Thus, if - attributes of each character are to be stored in a simple array, - such an array would be impractically big. The attributes usually - used, however, are often assigned only to a range of characters. - Even when all characters have attributes, characters of - consecutive character code tend to have the same attribute values. - - The m17n library utilizes this tendency to store characters and - their attribute values efficiently in an object called @e - Chartable. Although a chartable object is not a simple array, - application programs can handle chartables as if they were arrays. - Attribute values of a character can be obtained by accessing a - Chartable for the attribute with the character code of the - specified character. - - A chartable is a managed object. */ - -/***ja - @addtogroup m17nChartable ʸ»ú¥Æ¡¼¥Ö¥ë - - @brief ʸ»ú¥Æ¡¼¥Ö¥ë¤È¤½¤ì¤Ë´Ø¤¹¤ë API - - m17n ¥é¥¤¥Ö¥é¥ê¤¬°·¤¦Ê¸»ú¤Î¶õ´Ö¤Ï¹­Âç¤Ç¤¢¤ë¤¿¤á¡¢Ê¸»úËè¤Î¾ðÊó¤òñ - ½ã¤ÊÇÛÎó¤Ë³ÊǼ¤·¤è¤¦¤È¤¹¤ë¤È¡¢¤½¤ÎÇÛÎó¤ÏµðÂç¤Ë¤Ê¤ê¤¹¤®¡¢Èó¼ÂÍÑŪ¤Ç - ¤¢¤ë¡£¤·¤«¤·Ä̾ïɬÍפȤʤëʸ»ú¤Ë¤Ä¤¤¤Æ¤Î¾ðÊó¤Ï¡¢¤¢¤ëÆÃÄê¤ÎÈϰϤÎʸ - »ú¤Ë¤Î¤ßÉÕ¤¤¤Æ¤¤¤ë¤³¤È¤¬Â¿¤¤¡£Á´Ê¸»ú¤Ë´Ø¤·¤Æ¾ðÊ󤬤¢¤ë¾ì¹ç¤Ë¤â¡¢Ï¢ - ³¤·¤¿Ê¸»ú¥³¡¼¥É¤ò»ý¤Äʸ»ú¤ÏƱ¤¸¾ðÊó¤ò»ý¤Ä¤³¤È¤¬Â¿¤¤¡£¤½¤³¤Ç¡¢¤³¤Î - ¤è¤¦¤Ê¾õ¶·¤Ë¤ª¤¤¤Æ¸úΨŪ¤Ë¾ðÊó¤ò³ÊǼ¤Ç¤­¤ë¤â¤Î¤È¤·¤Æ¡¢m17n ¥é¥¤¥Ö - ¥é¥ê¤Ï @e ʸ»ú¥Æ¡¼¥Ö¥ë (chartable) ¤È¸Æ¤Ö¥ª¥Ö¥¸¥§¥¯¥È¤òÍѤ¤¤ë¡£¥¢ - ¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¡¢Ê¸»ú¥Æ¡¼¥Ö¥ë¤òÇÛÎó¤Î°ì¼ï¤È¸«¤Ê¤¹¤³¤È¤¬ - ¤Ç¤­¤ë¡£¤¢¤ëʸ»ú¤Ë¤Ä¤¤¤Æ¤ÎÆÃÄê¤Î¾ðÊó¤Ï¡¢¤½¤Î¾ðÊó¤ò»ý¤Äʸ»ú¥Æ¡¼¥Ö¥ë - ¤ò¤½¤Îʸ»ú¤Î¥³¡¼¥É¤Ç°ú¤¯¤³¤È¤ÇÆÀ¤é¤ì¤ë¡£ */ - -/*=*/ -#if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE) -/*** @addtogroup m17nInternal - @{ */ - -#include -#include -#include -#include -#include -#include - -#include "m17n.h" -#include "m17n-misc.h" -#include "internal.h" -#include "symbol.h" - -static M17NObjectArray chartable_table; - -/*** Maximum depth of char-table. */ -#define CHAR_TAB_MAX_DEPTH 3 - -/** @name Define: Number of characters covered by char-table of each level. - @{ */ - -/** BITs for number of characters covered by char-table of each - level. */ -#if MCHAR_MAX < 0x400000 - -#define SUB_BITS_0 22 /* i.e. 0x400000 chars */ -#define SUB_BITS_1 16 /* i.e. 0x10000 chars */ -#define SUB_BITS_2 12 /* i.e. 0x1000 chars */ -#define SUB_BITS_3 7 /* i.e. 0x80 chars */ - -#else /* MCHAR_MAX >= 0x400000 */ - -#define SUB_BITS_0 31 -#define SUB_BITS_1 24 -#define SUB_BITS_2 16 -#define SUB_BITS_3 8 -#endif - -/** @} */ - -/** How many characters a char-table covers at each level. */ -static const int chartab_chars[] = - { (1 << SUB_BITS_0), - (1 << SUB_BITS_1), - (1 << SUB_BITS_2), - (1 << SUB_BITS_3) }; - -/** How many slots a char-table has at each level. */ -static const int chartab_slots[] = - { (1 << (SUB_BITS_0 - SUB_BITS_1)), - (1 << (SUB_BITS_1 - SUB_BITS_2)), - (1 << (SUB_BITS_2 - SUB_BITS_3)), - (1 << SUB_BITS_3) }; - -/** Mask bits to obtain the valid bits from a character code for looking - up a char-table of each level. */ -static const int chartab_mask[] = - { (int) ((((unsigned) 1) << SUB_BITS_0) - 1), - (1 << SUB_BITS_1) - 1, - (1 << SUB_BITS_2) - 1, - (1 << SUB_BITS_3) - 1 }; - -/** Bit-shifting counts to obtain a valid index from a character code - for looking up a char-table of each level. */ -static const int chartab_shift[] = - { SUB_BITS_1, SUB_BITS_2, SUB_BITS_3, 0 }; - - -/** Index for looking up character C in a char-table at DEPTH. */ -#define SUB_IDX(depth, c) \ - (((c) & chartab_mask[depth]) >> chartab_shift[depth]) - - -/** Structure of sub char-table. */ -typedef struct MSubCharTable MSubCharTable; - -struct MSubCharTable -{ -#if SUB_BITS_0 > 24 - - /* The depth of the table; 0, 1, 2, or 3. */ - int depth; - - /* The minimum character covered by the table. */ - int min_char; - -#else /* SUB_BITS_0 <= 24 */ - - /* The value is (( << 24) | ). */ - int depth_min_char; - -#endif /* SUB_BITS_0 <= 24 */ - - /** The default value of characters covered by the table. */ - void *default_value; - - /** For a table of bottom level, array of values. For a non-bottom - table, array of sub char-tables. It may be NULL if all - characters covered by the table has . */ - union { - void **values; - MSubCharTable *tables; - } contents; -}; - -#if SUB_BITS_0 > 24 -#define TABLE_DEPTH(table) ((table)->depth) -#define TABLE_MIN_CHAR(table) ((table)->min_char) -#define SET_DEPTH_MIN_CHAR(table, DEPTH, MIN_CHAR) \ - ((table)->depth = (DEPTH), (table)->min_char = (MIN_CHAR)) -#else /* SUB_BITS_0 <= 24 */ -#define TABLE_DEPTH(table) ((table)->depth_min_char >> 24) -#define TABLE_MIN_CHAR(table) ((table)->depth_min_char & 0xFFFFFF) -#define SET_DEPTH_MIN_CHAR(table, DEPTH, MIN_CHAR) \ - ((table)->depth_min_char = ((DEPTH) << 24) | (MIN_CHAR)) -#endif /* SUB_BITS_0 <= 24 */ - -/** Structure of char-table. */ - -struct MCharTable -{ - /** Common header for a managed object. */ - M17NObject control; - - /** Key of the table. */ - MSymbol key; - - /** The minimum and maximum characters covered by the table. */ - int min_char, max_char; - - MSubCharTable subtable; -}; - - - - -/* Local functions. */ - -/** Allocate and initialize an array of sub-tables for sub char-table - TABLE. It is assumed that TABLE_DEPTH (TABLE) < - CHAR_TAB_MAX_DEPTH.*/ - -static void -make_sub_tables (MSubCharTable *table, int managedp) -{ - int depth = TABLE_DEPTH (table); - int min_char = TABLE_MIN_CHAR (table); - int slots = chartab_slots[depth]; - int chars = chartab_chars[depth + 1]; - MSubCharTable *tables; - int i; - - MTABLE_MALLOC (tables, slots, MERROR_CHARTABLE); - - for (i = 0; i < slots; i++, min_char += chars) - { - SET_DEPTH_MIN_CHAR (tables + i, depth + 1, min_char); - tables[i].default_value = table->default_value; - tables[i].contents.tables = NULL; - } - if (managedp && table->default_value) - M17N_OBJECT_REF_NTIMES (tables->default_value, slots); - table->contents.tables = tables; -} - - -/** Allocate and initialize an array of values for sub char-table - TABLE. It is assumed that TABLE_DEPTH (TABLE) == - CHAR_TAB_MAX_DEPTH. */ - -static void -make_sub_values (MSubCharTable *table, int managedp) -{ - int slots = chartab_slots[CHAR_TAB_MAX_DEPTH]; - void **values; - int i; - - MTABLE_MALLOC (values, slots, MERROR_CHARTABLE); - - for (i = 0; i < slots; i++) - values[i] = table->default_value; - if (managedp && table->default_value) - M17N_OBJECT_REF_NTIMES (table->default_value, slots); - table->contents.values = values; -} - - -/** Free contents of sub char-table TABLE and the default value of - TABLE. Free also the sub-tables recursively. */ - -static void -free_sub_tables (MSubCharTable *table, int managedp) -{ - int depth = TABLE_DEPTH (table); - int slots = chartab_slots[depth]; - - if (table->contents.tables) - { - if (depth < CHAR_TAB_MAX_DEPTH) - { - while (slots--) - free_sub_tables (table->contents.tables + slots, managedp); - free (table->contents.tables); - } - else - { - if (managedp) - while (slots--) - { - if (table->contents.values[slots]) - M17N_OBJECT_UNREF (table->contents.values[slots]); - } - free (table->contents.values); - } - table->contents.tables = NULL; - } - if (managedp && table->default_value) - M17N_OBJECT_UNREF (table->default_value); -} - - -/** In sub char-table TABLE, set value VAL for characters of the range - FROM and TO. */ - -static void -set_chartable_range (MSubCharTable *table, int from, int to, void *val, - int managedp) -{ - int depth = TABLE_DEPTH (table); - int min_char = TABLE_MIN_CHAR (table); - int max_char = min_char + (chartab_chars[depth] - 1); - int i; - - if (max_char < 0 || max_char > MCHAR_MAX) - max_char = MCHAR_MAX; - - if (from < min_char) - from = min_char; - if (to > max_char) - to = max_char; - - if (from == min_char && to == max_char) - { - free_sub_tables (table, managedp); - if (managedp && val) - M17N_OBJECT_REF (val); - table->default_value = val; - return; - } - - if (depth < CHAR_TAB_MAX_DEPTH) - { - if (! table->contents.tables) - make_sub_tables (table, managedp); - i = SUB_IDX (depth, from); - table = table->contents.tables + i; - while (i < chartab_slots[depth] && TABLE_MIN_CHAR (table) <= to) - { - set_chartable_range (table, from, to, val, managedp); - table++, i++; - } - } - else - { - int idx_from = SUB_IDX (depth, from); - int idx_to = SUB_IDX (depth, to); - - if (! table->contents.values) - make_sub_values (table, managedp); - for (i = idx_from; i <= idx_to; i++) - { - if (managedp && table->contents.values[i]) - M17N_OBJECT_UNREF (table->contents.values[i]); - table->contents.values[i] = val; - } - if (managedp && val) - M17N_OBJECT_REF_NTIMES (val, (idx_to - idx_from + 1)); - } -} - - -/** Lookup the sub char-table TABLE for the character C. If NEXT_C is - not NULL, set *NEXT_C to the next interesting character to lookup - for. If DEFAULT_P is zero, the next interesting character is what - possibly has the different value than C. Otherwise, the next - interesting character is what possibly has the default value (if C - has a value deferent from the default value) or has a value - different from the default value (if C has the default value). */ - -static void * -lookup_chartable (MSubCharTable *table, int c, int *next_c, int default_p) -{ - int depth = TABLE_DEPTH (table); - void *val; - void *default_value = table->default_value; - int idx; - - while (1) - { - if (! table->contents.tables) - { - if (next_c) - *next_c = TABLE_MIN_CHAR (table) + chartab_chars[depth]; - return table->default_value; - } - if (depth == CHAR_TAB_MAX_DEPTH) - break; - table = table->contents.tables + SUB_IDX (depth, c); - depth++; - } - - idx = SUB_IDX (depth, c); - val = table->contents.values[idx]; - - if (next_c) - { - int max_char = TABLE_MIN_CHAR (table) + (chartab_chars[depth] - 1); - - if (max_char < 0 || max_char > MCHAR_MAX) - max_char = MCHAR_MAX; - if (default_p && val != default_value) - { - do { c++, idx++; } - while (c >= 0 && c <= max_char - && table->contents.values[idx] != default_value); - } - else - { - do { c++, idx++; } - while (c >= 0 && c <= max_char - && table->contents.values[idx] == val); - } - *next_c = c; - } - return val; -} - -/** Call FUNC for characters in sub char-table TABLE. Ignore such - characters that has a value IGNORE. FUNC is called with four - arguments; FROM, TO, VAL, and ARG (same as FUNC_ARG). If - DEFAULT_P is zero, FROM and TO are range of characters that has - the same value VAL. Otherwise, FROM and TO are range of - characters that has the different value than the default value of - TABLE. */ - -static void -map_chartable (MSubCharTable *table, void *ignore, int default_p, - void (*func) (int, int, void *, void *), - void *func_arg) -{ - void *current; - int from = 0; - int c, next_c; - - current = lookup_chartable (table, 0, &next_c, default_p); - c = next_c; - while (c >= 0 && c <= MCHAR_MAX) - { - void *next = lookup_chartable (table, c, &next_c, default_p); - - if (current != next) - { - if (current != ignore) - (*func) (from, c - 1, current, func_arg); - current = next; - from = c; - } - c = next_c; - } - if (from <= MCHAR_MAX && current != ignore) - (*func) (from, MCHAR_MAX, current, func_arg); -} - - -/* Return the smallest character whose value is not DEFAULT_VALUE in - TABLE. If all characters in TABLE have DEFAULT_VALUE, return - -1. */ - -static int -chartab_min_non_default_char (MSubCharTable *table, void *default_value) -{ - int depth = TABLE_DEPTH (table); - int slots; - int i, c; - - if (!table->contents.tables) - return (default_value == table->default_value - ? -1 : TABLE_MIN_CHAR (table)); - - slots = chartab_slots[depth]; - - if (depth == CHAR_TAB_MAX_DEPTH) - { - for (i = 0; i < slots; i++) - if (table->contents.values[i] != default_value) - return (TABLE_MIN_CHAR (table) + i); - } - else - { - for (i = 0; i < slots; i++) - if ((c = chartab_min_non_default_char (table->contents.tables + i, - default_value)) - >= 0) - return c; - } - return -1; -} - - -/* Return the largest character whose value is not DEFAULT_VALUE in - TABLE. If all characters in TABLE have DEFAULT_VALUE, return - -1. */ - -static int -chartab_max_non_default_char (MSubCharTable *table, void *default_value) -{ - int depth = TABLE_DEPTH (table); - int slots; - int i, c; - - if (!table->contents.tables) - return (default_value == table->default_value - ? -1 : TABLE_MIN_CHAR (table) + chartab_chars[depth] - 1); - - slots = chartab_slots[depth]; - - if (depth == CHAR_TAB_MAX_DEPTH) - { - for (i = slots - 1; i >= 0; i--) - if (table->contents.values[i] != default_value) - return (TABLE_MIN_CHAR (table) + i); - } - else - { - for (i = slots - 1; i >= 0; i--) - if ((c = chartab_max_non_default_char (table->contents.tables + i, - default_value)) - >= 0) - return c; - } - return -1; -} - -static void -free_chartable (void *object) -{ - MCharTable *table = (MCharTable *) object; - int managedp = table->key != Mnil && table->key->managing_key; - - if (table->subtable.contents.tables) - { - int i; - - for (i = 0; i < chartab_slots[0]; i++) - free_sub_tables (table->subtable.contents.tables + i, managedp); - free (table->subtable.contents.tables); - if (managedp && table->subtable.default_value) - M17N_OBJECT_UNREF (table->subtable.default_value); - } - M17N_OBJECT_UNREGISTER (chartable_table, table); - free (object); -} - -#include - -/* Support function of mdebug_dump_chartab. */ - -static void -dump_sub_chartab (MSubCharTable *table, void *default_value, - MSymbol key, int indent) -{ - int depth = TABLE_DEPTH (table); - int min_char = TABLE_MIN_CHAR (table); - int max_char = min_char + (chartab_chars[depth] - 1); - char *prefix = (char *) alloca (indent + 1); - int i; - - if (max_char < 0 || max_char > MCHAR_MAX) - max_char = MCHAR_MAX; - - memset (prefix, 32, indent); - prefix[indent] = 0; - - if (! table->contents.tables && table->default_value == default_value) - return; - fprintf (stderr, "\n%s(sub%d (U+%04X U+%04X) ", - prefix, depth, min_char, max_char); - if (key == Msymbol) - { - if (table->default_value) - fprintf (stderr, "(default %s)", - ((MSymbol) table->default_value)->name); - else - fprintf (stderr, "(default nil)"); - } - else - fprintf (stderr, "(default #x%X)", (unsigned) table->default_value); - - default_value = table->default_value; - if (table->contents.tables) - { - if (depth < CHAR_TAB_MAX_DEPTH) - for (i = 0; i < chartab_slots[depth]; i++) - dump_sub_chartab (table->contents.tables + i, default_value, - key, indent + 2); - else - for (i = 0; i < chartab_slots[depth]; i++, min_char++) - { - void **val = table->contents.values + i; - - if (val == default_value) - continue; - default_value = *val; - fprintf (stderr, "\n%s (U+%04X", prefix, min_char); - while (i + 1 < chartab_slots[depth] - && val[1] == default_value) - i++, val++, min_char++; - fprintf (stderr, "-U+%04X ", min_char); - if (key == Msymbol) - { - if (default_value) - fprintf (stderr, "%s)", ((MSymbol) default_value)->name); - else - fprintf (stderr, "nil)"); - } - else - fprintf (stderr, " #xx%X)", (unsigned) default_value); - } - } - fprintf (stderr, ")"); -} - - -/* Internal API */ - -int -mchartable__init () -{ - chartable_table.count = 0; - return 0; -} - -void -mchartable__fini () -{ - mdebug__report_object ("Chartable", &chartable_table); -} - -void * -mchartable__lookup (MCharTable *table, int c, int *next_c, int default_p) -{ - return lookup_chartable (&table->subtable, c, next_c, default_p); -} - -/*** @} */ -#endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */ - - -/* External API */ - -/*** @addtogroup m17nChartable */ -/*** @{ */ -/*=*/ - -/***en - @brief Symbol whose name is "char-table". - - The symbol @c Mchar_table has the name "char-table". */ - -/***ja - @brief "char-table" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë - - ÊÑ¿ô @c Mchar_table ¤Ï̾Á° "char-table" ¤ò»ý¤ÄÄêµÁºÑ¤ß¥·¥ó - ¥Ü¥ë¤Ç¤¢¤ë¡£ */ - -MSymbol Mchar_table; - -/*=*/ - -/***en - @brief Create a new chartable. - - The mchartable () function creates a new chartable object with - symbol $KEY and the default value $DEFAULT_VALUE. If $KEY is a - managing key, the elements of the table (including the default - value) are managed objects or NULL. - - @return - If the operation was successful, mchartable () returns a pointer - to the created chartable. Otherwise it returns @c NULL and - assigns an error code to the external variable @c merror_code. */ - -/***ja - @brief ¿·¤·¤¤Ê¸»ú¥Æ¡¼¥Ö¥ë¤òºî¤ë - - ´Ø¿ô mchartable () ¤Ï¥­¡¼¤¬ $KEY ¤ÇÍ×ÁǤΥǥե©¥ë¥ÈÃͤ¬ - $DEFAULT_VALUE ¤Ç¤¢¤ë¿·¤·¤¤Ê¸»ú¥Æ¡¼¥Ö¥ë¤òºî¤ë¡£¤â¤· $KEY ¤¬´ÉÍý¥­¡¼ - ¤Ç¤¢¤ì¤Ð¡¢¤³¤Î¥Æ¡¼¥Ö¥ë¤ÎÍ×ÁǤϡʥǥե©¥ë¥ÈÃͤò´Þ¤á¤Æ¡Ë´ÉÍý²¼¥ª¥Ö¥¸¥§ - ¥¯¥È¤« NULL ¤Ç¤¢¤ë¡£ - - @return - ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mchartable () ¤ÏºîÀ®¤µ¤ì¤¿Ê¸»ú¥Æ¡¼¥Ö¥ë¤Ø¤Î¥Ý¥¤¥ó - ¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô @c merror_code ¤Ë¥¨ - ¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ */ - -MCharTable * -mchartable (MSymbol key, void *default_value) -{ - MCharTable *table; - - M17N_OBJECT (table, free_chartable, MERROR_CHARTABLE); - M17N_OBJECT_REGISTER (chartable_table, table); - table->key = key; - table->min_char = 0; - table->max_char = -1; - SET_DEPTH_MIN_CHAR (&table->subtable, 0, 0); - table->subtable.default_value = default_value; - if (key != Mnil && key->managing_key && default_value) - M17N_OBJECT_REF (default_value); - table->subtable.contents.tables = NULL; - return table; -} - -/*=*/ - -/***en - @brief Return the assigned value of a character in a chartable. - - The mchartable_lookup () function returns the value assigned to - character $C in chartable $TABLE. If no value has been set for $C - explicitly, the default value of $TABLE is returned. If $C is not - a valid character, mchartable_lookup () returns @c NULL and - assigns an error code to the external variable @c merror_code. */ - -/***ja - @brief ʸ»ú¥Æ¡¼¥Ö¥ëÃæ¤Çʸ»ú¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÃͤòÊÖ¤¹ - - ´Ø¿ô mchartable_lookup () ¤Ïʸ»ú¥Æ¡¼¥Ö¥ë $TABLE Ãæ¤Çʸ»ú $C ¤Ë³ä¤ê - Åö¤Æ¤é¤ì¤¿ÃͤòÊÖ¤¹¡£$C ¤ËÂФ¹¤ëÌÀ¼¨Åª¤ÊÃͤ¬¤Ê¤±¤ì¤Ð¡¢$TABLE ¤Î¥Ç¥Õ¥© - ¥ë¥ÈÃͤòÊÖ¤¹¡£$C ¤¬ÂÅÅö¤Êʸ»ú¤Ç¤Ê¤±¤ì¤Ð¡¢mchartable_lookup () ¤Ï - @c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô @c merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ */ - -/*** - @errors - @c MERROR_CHAR - - @seealso - mchartable_set () */ - -void * -mchartable_lookup (MCharTable *table, int c) -{ - M_CHECK_CHAR (c, NULL); - - if (c < table->min_char || c > table->max_char) - return table->subtable.default_value; - return lookup_chartable (&table->subtable, c, NULL, 0); -} - -/*=*/ - -/***en - @brief Assign a value to a character in a chartable. - - The mchartable_set () function sets the value of character $C in - chartable $TABLE to $VAL. - - @return - If the operation was successful, mchartable_set () returns 0. - Otherwise it returns -1 and assigns an error code to the external - variable @c merror_code. */ - -/***ja - @brief ʸ»ú¥Æ¡¼¥Ö¥ëÃæ¤Ç¤Îʸ»ú¤ÎÃͤòÀßÄꤹ¤ë - - ´Ø¿ô mchartable_set () ¤Ï¡¢Ê¸»ú¥Æ¡¼¥Ö¥ë $TABLE Ãæ¤Îʸ»ú $C ¤Ë - ÃÍ $VAL ¤ò³ä¤êÅö¤Æ¤ë¡£ - - @return - ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¡¢mchartable_set () ¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 - ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô @c merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ */ - -/*** - @errors - @c MERROR_CHAR - - @seealso - mchartable_lookup (), mchartable_set_range () */ - - -int -mchartable_set (MCharTable *table, int c, void *val) -{ - int managedp = table->key != Mnil && table->key->managing_key; - MSubCharTable *sub = &table->subtable; - int i; - - M_CHECK_CHAR (c, -1); - - if (table->max_char < 0) - table->min_char = table->max_char = c; - else - { - if (c < table->min_char) - table->min_char = c; - else if (c > table->max_char) - table->max_char = c; - } - - for (i = 0; i < CHAR_TAB_MAX_DEPTH; i++) - { - if (! sub->contents.tables) - { - if (sub->default_value == val) - return 0; - make_sub_tables (sub, managedp); - } - sub = sub->contents.tables + SUB_IDX (i, c); - } - if (! sub->contents.values) - { - if (sub->default_value == val) - return 0; - make_sub_values (sub, managedp); - } - sub->contents.values[SUB_IDX (3, c)] = val; - if (managedp && val) - M17N_OBJECT_REF (val); - return 0; -} - -/*=*/ - -/***en - @brief Assign a value to the characters in the specified range. - - The mchartable_set_range () function assigns value $VAL to the - characters from $FROM to $TO (both inclusive) in chartable $TABLE. - - @return - If the operation was successful, mchartable_set_range () returns - 0. Otherwise it returns -1 and assigns an error code to the - external variable @c merror_code. If $FROM is greater than $TO, - mchartable_set_range () returns immediately without an error. */ - -/***ja - @brief »ØÄêÈϰϤÎʸ»ú¤ÎÃͤòÀßÄꤹ¤ë - - ´Ø¿ô mchartable_set_range () ¤Ï¡¢Ê¸»ú¥Æ¡¼¥Ö¥ë $TABLE Ãæ¤Î $FROM ¤« - ¤é $TO ¤Þ¤Ç¡Êξü¤ò´Þ¤à¡Ë¤Îʸ»ú¤Ë¡¢ÃͤȤ·¤Æ $VAL ¤òÀßÄꤹ¤ë¡£ - - @return - ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mchartable_set_range () ¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð - -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô @c merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£$FROM ¤¬ - $TO ¤è¤êÂ礭¤¤¤È¤­¤Ë¤Ï¡¢ mchartable_set_range () ¤Ï²¿¤â¤»¤º¡¢¥¨¥é¡¼ - ¤âµ¯¤³¤µ¤Ê¤¤¡£ */ - -/*** - @errors - @c MERROR_CHAR - - @seealso - mchartable_set () */ - -int -mchartable_set_range (MCharTable *table, int from, int to, void *val) -{ - int managedp = table->key != Mnil && table->key->managing_key; - - M_CHECK_CHAR (from, -1); - M_CHECK_CHAR (to, -1); - - if (from > to) - return 0; - - if (table->max_char < 0) - table->min_char = from, table->max_char = to; - else{ - if (from < table->min_char) - table->min_char = from; - if (to > table->max_char) - table->max_char = to; - } - set_chartable_range (&table->subtable, from, to, val, managedp); - return 0; -} - -/*=*/ - -/***en - @brief Search for characters that have non-default value. - - The mchartable_range () function searches chartable $TABLE for the - first and the last character codes that do not have the default - value of $TABLE, and set $FROM and $TO to them, respectively. If - all characters have the default value, both $FROM and $TO are set - to -1. */ - -/***ja - @brief Ãͤ¬¥Ç¥Õ¥©¥ë¥È¤È°Û¤Ê¤ëʸ»ú¤òõ¤¹ - - ´Ø¿ô mchartable_range () ¤Ïʸ»ú¥Æ¡¼¥Ö¥ë $TABLE Ãæ¤Ç¡¢$TABLE ¤Î¥Ç¥Õ¥© - ¥ë¥ÈÃͰʳ°¤ÎÃͤò»ý¤ÄºÇ½é¤ÈºÇ¸å¤Îʸ»ú¤òÄ´¤Ù¡¢¤½¤ì¤¾¤ì¤ò $FROM ¤È - $TO ¤ËÀßÄꤹ¤ë¡£¤¹¤Ù¤Æ¤Îʸ»ú¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤòÃͤȤ·¤Æ»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢ - $FROM ¤È $TO ¤ò -1¤ËÀßÄꤹ¤ë¡£ */ - -void -mchartable_range (MCharTable *table, int *from, int *to) -{ - *from = chartab_min_non_default_char (&table->subtable, - table->subtable.default_value); - if (*from == -1) - *to = -1; - else - *to = chartab_max_non_default_char (&table->subtable, - table->subtable.default_value); -} - -/*=*/ - -/***en - @brief Call a function for characters in a chartable. - - The mchartable_map () function calls function $FUNC for characters - in chartable $TABLE. No function call occurs for characters that - have value $IGNORE in $TABLE. Comparison of $IGNORE and character - value is done with the operator @c ==. Be careful when you use - string literals or pointers. - - Instead of calling $FUNC for each character, mchartable_map () - tries to optimize the number of function calls, i.e. it makes a - single function call for a chunk of characters when those - consecutive characters have the same value. - - No matter how long the character chunk is, $FUNC is called with - four arguments; $FROM, $TO, $VAL, and $ARG. $FROM and $TO (both - inclusive) defines the range of characters that have value $VAL. - $ARG is the same as $FUNC_ARG. - - @return - This function always returns 0. */ - -/***ja - @brief ʸ»ú¥Æ¡¼¥Ö¥ëÃæ¤Îʸ»ú¤ËÂФ·¤Æ»ØÄê¤Î´Ø¿ô¤ò¸Æ¤Ö - - ´Ø¿ô mchartable_map () ¤Ï¡¢Ê¸»ú¥Æ¡¼¥Ö¥ë $TABLE Ãæ¤Îʸ»ú¤ËÂФ·¤Æ´Ø - ¿ô $FUNC ¤ò¸Æ¤Ö¡£¤¿¤À¤·Ãͤ¬ $IGNORE ¤Ç¤¢¤ëʸ»ú¤Ë¤Ä¤¤¤Æ¤Ï´Ø¿ô¸Æ¤Ó½Ð - ¤·¤ò¹Ô¤Ê¤ï¤Ê¤¤¡£$IGNORE ¤Èʸ»ú¤ÎÃͤÎÈæ³Ó¤Ï @c == ¤Ç¹Ô¤Ê¤¦¤Î¤Ç¡¢Ê¸»úÎó - ¥ê¥Æ¥é¥ë¤ä¥Ý¥¤¥ó¥¿¤ò»È¤¦ºÝ¤Ë¤ÏÃí°Õ¤òÍפ¹¤ë¡£ - - mchartable_map () ¤Ï¡¢°ìʸ»ú¤´¤È¤Ë $FUNC ¤ò¸Æ¤Ö¤Î¤Ç¤Ï¤Ê¤¯¡¢´Ø¿ô¸Æ - ¤Ó½Ð¤·¤Î²ó¿ô¤òºÇŬ²½¤·¤è¤¦¤È¤¹¤ë¡£¤¹¤Ê¤ï¤Á¡¢Ï¢Â³¤·¤¿Ê¸»ú¤¬Æ±¤¸Ãͤò - »ý¤Ã¤Æ¤¤¤¿¾ì¹ç¤Ë¤Ï¡¢¤½¤Îʸ»ú¤Î¤Þ¤È¤Þ¤êÁ´ÂΤˤĤ¤¤Æ°ìÅ٤δؿô¸Æ¤Ó½Ð - ¤·¤·¤«¹Ô¤Ê¤ï¤Ê¤¤¡£ - - ʸ»ú¤Î¤Þ¤È¤Þ¤ê¤ÎÂ礭¤µ¤Ë¤«¤«¤ï¤é¤º¡¢$FUNC ¤Ï $FROM, $TO, $VAL, $ARG - ¤Î£´°ú¿ô¤Ç¸Æ¤Ð¤ì¤ë¡£$FROM ¤È $TO ¡Êξü¤ò´Þ¤à¡Ë¤Ï $VAL ¤òÃͤȤ·¤Æ - »ý¤Äʸ»ú¤ÎÈϰϤò¼¨¤·¡¢$ARG ¤Ï $FUNC_ARG ¤½¤Î¤â¤Î¤Ç¤¢¤ë¡£ - - @return - ¤³¤Î´Ø¿ô¤Ï¾ï¤Ë0¤òÊÖ¤¹¡£ */ - -int -mchartable_map (MCharTable *table, void *ignore, - void (*func) (int, int, void *, void *), - void *func_arg) -{ - map_chartable (&table->subtable, ignore, 0, func, func_arg); - return 0; -} - -/*=*/ - -/*** @} */ - -/*** @addtogroup m17nDebug */ -/*=*/ -/*** @{ */ - -/***en - @brief Dump a chartable. - - The mdebug_dump_chartab () function prints a chartable $TABLE in a - human readable way to the stderr. $INDENT specifies how many - columns to indent the lines but the first one. - - @return - This function returns $TABLE. */ - -MCharTable * -mdebug_dump_chartab (MCharTable *table, int indent) -{ - fprintf (stderr, "(chartab (U+%04X U+%04X)", - table->min_char, table->max_char); - dump_sub_chartab (&table->subtable, table->subtable.default_value, - table->key, indent + 2); - fprintf (stderr, ")"); - return table; -} - -/*** @} */ - -/* - Local Variables: - coding: euc-japan - End: -*/ diff --git a/src/chartab.h b/src/chartab.h deleted file mode 100644 index 715acbf..0000000 --- a/src/chartab.h +++ /dev/null @@ -1,30 +0,0 @@ -/* chartab.h -- header file for the character table module. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -#ifndef _M17N_CHARTAB_H_ -#define _M17N_CHARTAB_H_ - -extern void *mchartable__lookup (MCharTable *table, int c, - int *next_c, int default_p); - -#endif /* not _M17N_CHARTAB_H_ */ - diff --git a/src/coding.c b/src/coding.c deleted file mode 100644 index 3828d2c..0000000 --- a/src/coding.c +++ /dev/null @@ -1,4863 +0,0 @@ -/* coding.c -- code conversion module. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -/***en - @addtogroup m17nConv - @brief Coding system objects and API for them. - - The m17n library represents a character encoding scheme (CES) of - coded character sets (CCS) as an object called @e coding @e - system. Application programs can add original coding systems. - - To @e encode means converting code-points to character codes and - to @e decode means converting character codes back to code-points. - - Application programs can decode a byte sequence with a specified - coding system into an M-text, and inversely, can encode an M-text - into a byte sequence. */ - -/***ja - @addtogroup m17nConv - @brief ¥³¡¼¥É·Ï¥ª¥Ö¥¸¥§¥¯¥È¤È¤½¤ì¤Ë´Ø¤¹¤ë API - - m17n ¥é¥¤¥Ö¥é¥ê¤Ï¡¢Éä¹æ²½Ê¸»ú½¸¹ç (coded character sets; CCS) ¤Îʸ - »úÉä¹ç²½Êý¼° (character encoding scheme; CES) ¤ò @e ¥³¡¼¥É·Ï ¤È¸Æ - ¤Ö¥ª¥Ö¥¸¥§¥¯¥È¤Çɽ¸½¤¹¤ë¡£m17n ¥é¥¤¥Ö¥é¥ê¤¬¥µ¥Ý¡¼¥È¤¹¤ëCES ¤Ï¡¢ - UTF-8, UTF-16, ISO-2022, DIRECT-CHARSET, ¤½¤Î¾¡¢¤ËÂçÊ̤µ¤ì¤ë¡£¥¢ - ¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤¬Æȼ«¤Ë¥³¡¼¥É·Ï¤òÄɲ乤뤳¤È¤â²Äǽ¤Ç¤¢¤ë¡£ - - ¥³¡¼¥É¥Ý¥¤¥ó¥È¤«¤éʸ»ú¥³¡¼¥É¤Ø¤ÎÊÑ´¹¤ò @e ¥¨¥ó¥³¡¼¥É ¤È¸Æ¤Ó¡¢Ê¸»ú - ¥³¡¼¥É¤«¤é¥³¡¼¥É¥Ý¥¤¥ó¥È¤Ø¤ÎÊÑ´¹¤ò @e ¥Ç¥³¡¼¥É ¤È¸Æ¤Ö¡£ - - ¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¡¢»ØÄꤵ¤ì¤¿¥³¡¼¥É·Ï¤Ç¥Ð¥¤¥ÈÎó¤ò¥Ç¥³¡¼ - ¥É¤¹¤ë¤³¤È¤Ç M-text ¤òÆÀ¤ë¤³¤È¤¬¤Ç¤­¤ë¡£¤Þ¤¿µÕ¤Ë¡¢»ØÄꤵ¤ì¤¿¥³¡¼¥É - ·Ï¤Ç M-text ¤ò¥¨¥ó¥³¡¼¥É¤·¤¹¤ë¤³¤È¤Ç¥Ð¥¤¥ÈÎó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤­¤ë¡£ */ - -/*=*/ - -#if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE) -/*** @addtogroup m17nInternal - @{ */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "m17n.h" -#include "m17n-misc.h" -#include "internal.h" -#include "plist.h" -#include "character.h" -#include "charset.h" -#include "coding.h" -#include "mtext.h" -#include "symbol.h" -#include "mlocale.h" - -#define NUM_SUPPORTED_CHARSETS 32 - -/** Structure for coding system object. */ - -typedef struct -{ - /** Name of the coding system. */ - MSymbol name; - - /** Type of the coding system. */ - MSymbol type; - - /* Number of supported charsets. */ - int ncharsets; - - /** Array of supported charsets. */ - MCharset *charsets[NUM_SUPPORTED_CHARSETS]; - - /** If non-NULL, function to call at the time of creating and - reseting a converter. */ - int (*resetter) (MConverter *converter); - - int (*decoder) (unsigned char *str, int str_bytes, MText *mt, - MConverter *converter); - - int (*encoder) (MText *mt, int from, int to, - unsigned char *str, int str_bytes, - MConverter *converter); - - /** If non-zero, the coding system decode/encode ASCII characters as - is. */ - int ascii_compatible; - - /** Pointer to extra information given when the coding system is - defined. The meaning depends on . */ - void *extra_info; - - /** Pointer to information referred on conversion. The meaning - depends on . The value NULL means that the coding system - is not yet setup. */ - void *extra_spec; - - int ready; -} MCodingSystem; - -struct MCodingList -{ - int size, inc, used; - MCodingSystem **codings; -}; - -static struct MCodingList coding_list; - -static MPlist *coding_definition_list; - -typedef struct { - /**en - Pointer to a structure of a coding system. */ - /**ja - ¥³¡¼¥É·Ï¤òɽ¤ï¤¹¥Ç¡¼¥¿¹½Â¤¤Ø¤Î¥Ý¥¤¥ó¥¿ */ - MCodingSystem *coding; - - /**en - Buffer for carryover bytes generated while decoding. */ - /**ja - ¥Ç¥³¡¼¥ÉÃæ¤Î¥­¥ã¥ê¥£¥ª¡¼¥Ð¡¼¥Ð¥¤¥ÈÍѥХåե¡ */ - unsigned char carryover[256]; - - /**en - Number of carryover bytes. */ - /**ja - ¥­¥ã¥ê¥£¥ª¡¼¥Ð¡¼¥Ð¥¤¥È¿ô */ - int carryover_bytes; - - /**en - Beginning of the byte sequence bound to this converter. */ - /**ja - ¤³¤Î¥³¥ó¥Ð¡¼¥¿¤Ë·ë¤ÓÉÕ¤±¤é¤ì¤¿¥Ð¥¤¥ÈÎó¤ÎÀèƬ°ÌÃÖ */ - unsigned char *buf; - - /**en - Size of buf. */ - /**ja - buf ¤ÎÂ礭¤µ */ - int bufsize; - - /**en - Number of bytes already consumed in buf. */ - /**ja - buf Æâ¤Ç¤¹¤Ç¤Ë¾ÃÈñ¤µ¤ì¤¿¥Ð¥¤¥È¿ô */ - int used; - - /**en - Stream bound to this converter. */ - /**ja - ¤³¤Î¥³¥ó¥Ð¡¼¥¿¤Ë·ë¤ÓÉÕ¤±¤é¤ì¤¿¥¹¥È¥ê¡¼¥à */ - FILE *fp; - - /**en - Which of above two is in use. */ - /**ja - ¾åµ­2¼Ô¤Î¤¤¤º¤ì¤¬»È¤ï¤ì¤Æ¤¤¤ë¤« */ - int binding; - - /**en - Buffer for unget. */ - /**ja - Unget ÍѥХåե¡ */ - MText *unread; - - /*en - Working area. */ - /*ja - ºî¶ÈÎΰè */ - MText *work_mt; - - int seekable; -} MConverterStatus; - - - -/* Local macros and functions. */ - -/** At first, set SRC_BASE to SRC. Then check if we have already - produced AT_MOST chars. If so, set SRC_END to SRC, and jump to - source_end. Otherwise, get one more byte C from SRC. In that - case, if SRC == SRC_END, jump to the label source_end. */ - -#define ONE_MORE_BASE_BYTE(c) \ - do { \ - src_base = src; \ - if (nchars == at_most) \ - { \ - src_end = src; \ - goto source_end; \ - } \ - if (src == src_stop) \ - { \ - if (src == src_end) \ - goto source_end; \ - src_base = src = source; \ - if (src == src_end) \ - goto source_end; \ - src_stop = src_end; \ - } \ - (c) = *src++; \ - } while (0) - - -/** Get one more byte C from SRC. If SRC == SRC_END, jump to the - label source_end. */ - -#define ONE_MORE_BYTE(c) \ - do { \ - if (src == src_stop) \ - { \ - if (src == src_end) \ - goto source_end; \ - src = source; \ - if (src == src_end) \ - goto source_end; \ - src_stop = src_end; \ - } \ - (c) = *src++; \ - } while (0) - - -#define REWIND_SRC_TO_BASE() \ - do { \ - if (src_base < source || src_base >= src_end) \ - src_stop = internal->carryover + internal->carryover_bytes; \ - src = src_base; \ - } while (0) - - -/** Push back byte C to SRC. */ - -#define UNGET_ONE_BYTE(c) \ - do { \ - if (src > source) \ - src--; \ - else \ - { \ - internal->carryover[0] = c; \ - internal->carryover_bytes = 1; \ - src = internal->carryover; \ - src_stop = src + 1; \ - } \ - } while (0); - - -/** Store multibyte representation of character C at DST and increment - DST to the next of the produced bytes. DST must be a pointer to - data area of M-text MT. If the produced bytes are going to exceed - DST_END, enlarge the data area of MT. */ - -#define EMIT_CHAR(c) \ - do { \ - int bytes = CHAR_BYTES (c); \ - int len; \ - \ - if (dst + bytes + 1 > dst_end) \ - { \ - len = dst - mt->data; \ - bytes = mt->allocated + bytes + (src_stop - src); \ - mtext__enlarge (mt, bytes); \ - dst = mt->data + len; \ - dst_end = mt->data + mt->allocated; \ - } \ - dst += CHAR_STRING (c, dst); \ - nchars++; \ - } while (0) - - -/* Check if there is enough room to produce LEN bytes at DST. If not, - go to the label insufficient_destination. */ - -#define CHECK_DST(len) \ - do { \ - if (dst + (len) > dst_end) \ - goto insufficient_destination; \ - } while (0) - - -/** Take NUM_CHARS characters (NUM_BYTES bytes) already stored at - (MT->data + MT->nbytes) into MT, and put charset property on - them with CHARSET->name. */ - -#define TAKEIN_CHARS(mt, num_chars, num_bytes, charset) \ - do { \ - int chars = (num_chars); \ - \ - if (chars > 0) \ - { \ - mtext__takein ((mt), chars, (num_bytes)); \ - if (charset) \ - mtext_put_prop ((mt), (mt)->nchars - chars, (mt)->nchars, \ - Mcharset, (void *) ((charset)->name)); \ - } \ - } while (0) - - -#define SET_SRC(mt, format, from, to) \ - do { \ - if (format <= MTEXT_FORMAT_UTF_8) \ - { \ - src = mt->data + POS_CHAR_TO_BYTE (mt, from); \ - src_end = mt->data + POS_CHAR_TO_BYTE (mt, to); \ - } \ - else if (format <= MTEXT_FORMAT_UTF_16BE) \ - { \ - src \ - = mt->data + (sizeof (short)) * POS_CHAR_TO_BYTE (mt, from); \ - src_end \ - = mt->data + (sizeof (short)) * POS_CHAR_TO_BYTE (mt, to); \ - } \ - else \ - { \ - src = mt->data + (sizeof (int)) * from; \ - src_end = mt->data + (sizeof (int)) * to; \ - } \ - } while (0) - - -#define ONE_MORE_CHAR(c, bytes, format) \ - do { \ - if (src == src_end) \ - goto finish; \ - if (format <= MTEXT_FORMAT_UTF_8) \ - c = STRING_CHAR_AND_BYTES (src, bytes); \ - else if (format <= MTEXT_FORMAT_UTF_16BE) \ - { \ - c = mtext_ref_char (mt, from++); \ - bytes = (sizeof (short)) * CHAR_UNITS_UTF16 (c); \ - } \ - else \ - { \ - c = ((unsigned *) (mt->data))[from++]; \ - bytes = sizeof (int); \ - } \ - } while (0) - - -static int -encode_unsupporeted_char (int c, unsigned char *dst, unsigned char *dst_end, - MText *mt, int pos) -{ - int len; - char *format; - - len = c < 0x10000 ? 8 : 10; - if (dst + len > dst_end) - return 0; - - format = (c < 0xD800 ? "" - : c < 0xE000 ? "" - : c < 0x10000 ? "" - : c < 0x110000 ? "" - : ""); - sprintf ((char *) dst, format, c); - return len; -} - - - -/** Finish decoding of bytes at SOURCE (ending at SRC_END) into NCHARS - characters by CONVERTER into M-text MT. SRC is a pointer to the - not-yet processed bytes. ERROR is 1 iff an invalid byte was - found. */ - -static int -finish_decoding (MText *mt, MConverter *converter, int nchars, - unsigned char *source, unsigned char *src_end, - unsigned char *src, - int error) -{ - MConverterStatus *internal = (MConverterStatus *) converter->internal_info; - - if (src == src_end) - internal->carryover_bytes = 0; - else if (error - || (converter->last_block - && ! converter->lenient)) - converter->result = MCONVERSION_RESULT_INVALID_BYTE; - else if (! converter->last_block) - { - unsigned char *dst = internal->carryover; - - if (src < source || src > src_end) - { - dst += internal->carryover_bytes; - src = source; - } - while (src < src_end) - *dst++ = *src++; - internal->carryover_bytes = dst - internal->carryover; - converter->result = MCONVERSION_RESULT_INSUFFICIENT_SRC; - } - else - { - unsigned char *dst = mt->data + mt->nbytes; - unsigned char *dst_end = mt->data + mt->allocated; - unsigned char *src_stop = src_end; - int c; - int last_nchars = nchars; - - if (src < source || src > src_end) - src_stop = internal->carryover + internal->carryover_bytes; - while (1) - { - if (converter->at_most && nchars == converter->at_most) - break; - if (src == src_stop) - { - if (src == src_end) - break; - src = source; - if (src == src_end) - break; - src_stop = src_end; - } - c = *src++; - EMIT_CHAR (c); - } - TAKEIN_CHARS (mt, nchars - last_nchars, dst - (mt->data + mt->nbytes), - mcharset__binary); - internal->carryover_bytes = 0; - } - - converter->nchars += nchars; - converter->nbytes += ((src < source || src > src_end) ? 0 : src - source); - return (converter->result == MCONVERSION_RESULT_INVALID_BYTE ? -1 : 0); -} - - - -/* Staffs for coding-systems of type MCODING_TYPE_CHARSET. */ - -static int -setup_coding_charset (MCodingSystem *coding) -{ - int ncharsets = coding->ncharsets; - unsigned *code_charset_table; - - if (ncharsets > 1) - { - /* At first, reorder charset list by dimensions (a charset of - smaller dimension comes first). As the number of charsets is - usually very small (at most 32), we do a simple sort. */ - MCharset **charsets; - int idx = 0; - int i, j; - - MTABLE_ALLOCA (charsets, NUM_SUPPORTED_CHARSETS, MERROR_CODING); - memcpy (charsets, coding->charsets, - sizeof (MCharset *) * NUM_SUPPORTED_CHARSETS); - for (i = 0; i < 4; i++) - for (j = 0; j < ncharsets; j++) - if (charsets[j]->dimension == i) - coding->charsets[idx++] = charsets[j]; - } - - MTABLE_CALLOC (code_charset_table, 256, MERROR_CODING); - while (ncharsets--) - { - int dim = coding->charsets[ncharsets]->dimension; - int from = coding->charsets[ncharsets]->code_range[(dim - 1) * 4]; - int to = coding->charsets[ncharsets]->code_range[(dim - 1) * 4 + 1]; - - if (coding->charsets[ncharsets]->ascii_compatible) - coding->ascii_compatible = 1; - while (from <= to) - code_charset_table[from++] |= 1 << ncharsets; - } - - coding->extra_spec = (void *) code_charset_table; - return 0; -} - -static int -reset_coding_charset (MConverter *converter) -{ - MConverterStatus *internal = (MConverterStatus *) converter->internal_info; - MCodingSystem *coding = internal->coding; - - if (! coding->ready - && setup_coding_charset (coding) < 0) - return -1; - coding->ready = 1; - return 0; -} - -static int -decode_coding_charset (unsigned char *source, int src_bytes, MText *mt, - MConverter *converter) -{ - MConverterStatus *internal = (MConverterStatus *) converter->internal_info; - MCodingSystem *coding = internal->coding; - unsigned char *src = internal->carryover; - unsigned char *src_stop = src + internal->carryover_bytes; - unsigned char *src_end = source + src_bytes; - unsigned char *src_base; - unsigned char *dst = mt->data + mt->nbytes; - unsigned char *dst_end = mt->data + mt->allocated; - int nchars = 0; - int last_nchars = 0; - int at_most = converter->at_most > 0 ? converter->at_most : -1; - - unsigned *code_charset_table = (unsigned *) coding->extra_spec; - MCharset **charsets = coding->charsets; - MCharset *charset = mcharset__ascii; - int error = 0; - - while (1) - { - MCharset *this_charset = NULL; - int c; - unsigned mask; - - ONE_MORE_BASE_BYTE (c); - mask = code_charset_table[c]; - if (mask) - { - int idx = 0; - unsigned code = c; - int nbytes = 1; - int dim; - - while (mask) - { - while (! (mask & 1)) mask >>= 1, idx++; - this_charset = charsets[idx]; - dim = this_charset->dimension; - while (nbytes < dim) - { - ONE_MORE_BYTE (c); - code = (code << 8) | c; - nbytes++; - } - c = DECODE_CHAR (this_charset, code); - if (c >= 0) - goto emit_char; - mask >>= 1, idx++; - } - } - - if (! converter->lenient) - break; - REWIND_SRC_TO_BASE (); - c = *src++; - this_charset = mcharset__binary; - - emit_char: - if (this_charset != mcharset__ascii - && this_charset != charset) - { - TAKEIN_CHARS (mt, nchars - last_nchars, - dst - (mt->data + mt->nbytes), charset); - charset = this_charset; - last_nchars = nchars; - } - EMIT_CHAR (c); - } - /* We reach here because of an invalid byte. */ - error = 1; - - source_end: - TAKEIN_CHARS (mt, nchars - last_nchars, - dst - (mt->data + mt->nbytes), charset); - return finish_decoding (mt, converter, nchars, - source, src_end, src_base, error); -} - -static int -encode_coding_charset (MText *mt, int from, int to, - unsigned char *destination, int dst_bytes, - MConverter *converter) -{ - MConverterStatus *internal = (MConverterStatus *) converter->internal_info; - MCodingSystem *coding = internal->coding; - unsigned char *src, *src_end; - unsigned char *dst = destination; - unsigned char *dst_end = dst + dst_bytes; - int nchars = 0; - int ncharsets = coding->ncharsets; - MCharset **charsets = coding->charsets; - int ascii_compatible = coding->ascii_compatible; - enum MTextFormat format = mt->format; - - SET_SRC (mt, format, from, to); - while (1) - { - int c, bytes; - - ONE_MORE_CHAR (c, bytes, format); - - if (c < 0x80 && ascii_compatible) - { - CHECK_DST (1); - *dst++ = c; - } - else - { - unsigned code; - MCharset *charset = NULL; - int i = 0; - - while (1) - { - charset = charsets[i]; - code = ENCODE_CHAR (charset, c); - if (code != MCHAR_INVALID_CODE) - break; - if (++i == ncharsets) - goto unsupported_char; - } - - CHECK_DST (charset->dimension); - if (charset->dimension == 1) - { - *dst++ = code; - } - else if (charset->dimension == 2) - { - *dst++ = code >> 8; - *dst++ = code & 0xFF; - } - else if (charset->dimension == 3) - { - *dst++ = code >> 16; - *dst++ = (code >> 8) & 0xFF; - *dst++ = code & 0xFF; - } - else - { - *dst++ = code >> 24; - *dst++ = (code >> 16) & 0xFF; - *dst++ = (code >> 8) & 0xFF; - *dst++ = code & 0xFF; - } - } - src += bytes; - nchars++; - continue; - - unsupported_char: - { - int len; - - if (! converter->lenient) - break; - len = encode_unsupporeted_char (c, dst, dst_end, mt, from + nchars); - if (len == 0) - goto insufficient_destination; - dst += len; - src += bytes; - nchars++; - } - } - /* We reach here because of an unsupported char. */ - converter->result = MCONVERSION_RESULT_INVALID_CHAR; - goto finish; - - insufficient_destination: - converter->result = MCONVERSION_RESULT_INSUFFICIENT_DST; - - finish: - converter->nchars += nchars; - converter->nbytes += dst - destination; - return (converter->result == MCONVERSION_RESULT_INVALID_CHAR ? -1 : 0); -} - - -/* Staffs for coding-systems of type MCODING_TYPE_UTF (8). */ - -#define UTF8_CHARSET(p) \ - (! ((p)[0] & 0x80) ? (mcharset__unicode) \ - : CHAR_HEAD_P ((p) + 1) ? (mcharset__binary) \ - : ! ((p)[0] & 0x20) ? (mcharset__unicode) \ - : CHAR_HEAD_P ((p) + 2) ? (mcharset__binary) \ - : ! ((p)[0] & 0x10) ? (mcharset__unicode) \ - : CHAR_HEAD_P ((p) + 3) ? (mcharset__binary) \ - : ! ((p)[0] & 0x08) ? ((((((p)[0] & 0x07) << 2) \ - & (((p)[1] & 0x30) >> 4)) <= 0x10) \ - ? (mcharset__unicode) \ - : (mcharset__m17n)) \ - : CHAR_HEAD_P ((p) + 4) ? (mcharset__binary) \ - : ! ((p)[0] & 0x04) ? (mcharset__m17n) \ - : CHAR_HEAD_P ((p) + 5) ? (mcharset__binary) \ - : ! ((p)[0] & 0x02) ? (mcharset__m17n) \ - : (mcharset__binary)) - - -static int -decode_coding_utf_8 (unsigned char *source, int src_bytes, MText *mt, - MConverter *converter) -{ - MConverterStatus *internal = (MConverterStatus *) converter->internal_info; - MCodingSystem *coding = internal->coding; - unsigned char *src = internal->carryover; - unsigned char *src_stop = src + internal->carryover_bytes; - unsigned char *src_end = source + src_bytes; - unsigned char *src_base; - unsigned char *dst = mt->data + mt->nbytes; - unsigned char *dst_end = mt->data + mt->allocated; - int nchars = 0; - int last_nchars = 0; - int at_most = converter->at_most > 0 ? converter->at_most : -1; - int error = 0; - int full = converter->lenient || (coding->charsets[0] == mcharset__m17n); - MCharset *charset = NULL; - - while (1) - { - int c, c1, bytes; - MCharset *this_charset = NULL; - - ONE_MORE_BASE_BYTE (c); - - if (!(c & 0x80)) - bytes = 1; - else if (!(c & 0x40)) - goto invalid_byte; - else if (!(c & 0x20)) - bytes = 2, c &= 0x1F; - else if (!(c & 0x10)) - bytes = 3, c &= 0x0F; - else if (!(c & 0x08)) - bytes = 4, c &= 0x07; - else if (!(c & 0x04)) - bytes = 5, c &= 0x03; - else if (!(c & 0x02)) - bytes = 6, c &= 0x01; - else - goto invalid_byte; - - while (bytes-- > 1) - { - ONE_MORE_BYTE (c1); - if ((c1 & 0xC0) != 0x80) - goto invalid_byte; - c = (c << 6) | (c1 & 0x3F); - } - - if (full - || c < 0xD800 || (c >= 0xE000 && c < 0x110000)) - goto emit_char; - - invalid_byte: - if (! converter->lenient) - break; - REWIND_SRC_TO_BASE (); - c = *src++; - this_charset = mcharset__binary; - - emit_char: - if (this_charset != charset) - { - TAKEIN_CHARS (mt, nchars - last_nchars, - dst - (mt->data + mt->nbytes), charset); - charset = this_charset; - last_nchars = nchars; - } - EMIT_CHAR (c); - } - /* We reach here because of an invalid byte. */ - error = 1; - - source_end: - TAKEIN_CHARS (mt, nchars - last_nchars, - dst - (mt->data + mt->nbytes), charset); - return finish_decoding (mt, converter, nchars, - source, src_end, src_base, error); -} - -static int -encode_coding_utf_8 (MText *mt, int from, int to, - unsigned char *destination, int dst_bytes, - MConverter *converter) -{ - MConverterStatus *internal = (MConverterStatus *) converter->internal_info; - MCodingSystem *coding = internal->coding; - unsigned char *src, *src_end; - unsigned char *dst = destination; - unsigned char *dst_end = dst + dst_bytes; - int nchars = 0; - enum MTextFormat format = mt->format; - - SET_SRC (mt, format, from, to); - - if (format <= MTEXT_FORMAT_UTF_8 - && (converter->lenient - || coding->charsets[0] == mcharset__m17n)) - { - if (dst_bytes < src_end - src) - { - int byte_pos = (src + dst_bytes) - mt->data; - - to = POS_BYTE_TO_CHAR (mt, byte_pos); - byte_pos = POS_CHAR_TO_BYTE (mt, to); - src_end = mt->data + byte_pos; - converter->result = MCONVERSION_RESULT_INSUFFICIENT_DST; - } - memcpy (destination, src, src_end - src); - nchars = to - from; - dst += src_end - src; - goto finish; - } - - while (1) - { - int c, bytes; - - ONE_MORE_CHAR (c, bytes, format); - - if ((c >= 0xD800 && c < 0xE000) || c >= 0x110000) - break; - CHECK_DST (bytes); - dst += CHAR_STRING (c, dst); - src += bytes; - nchars++; - } - /* We reach here because of an unsupported char. */ - converter->result = MCONVERSION_RESULT_INVALID_CHAR; - goto finish; - - insufficient_destination: - converter->result = MCONVERSION_RESULT_INSUFFICIENT_DST; - - finish: - converter->nchars += nchars; - converter->nbytes += dst - destination; - return (converter->result == MCONVERSION_RESULT_INVALID_CHAR ? -1 : 0); -} - - -/* Staffs for coding-systems of type MCODING_TYPE_UTF (16 & 32). */ - -enum utf_bom - { - UTF_BOM_MAYBE, - UTF_BOM_NO, - UTF_BOM_YES, - UTF_BOM_MAX - }; - -enum utf_endian - { - UTF_BIG_ENDIAN, - UTF_LITTLE_ENDIAN, - UTF_ENDIAN_MAX - }; - -struct utf_status -{ - int surrogate; - enum utf_bom bom; - enum utf_endian endian; -}; - -static int -setup_coding_utf (MCodingSystem *coding) -{ - MCodingInfoUTF *info = (MCodingInfoUTF *) (coding->extra_info); - MCodingInfoUTF *spec; - - if (info->code_unit_bits == 8) - coding->ascii_compatible = 1; - else if (info->code_unit_bits == 16 - || info->code_unit_bits == 32) - { - if (info->bom < 0 || info->bom > 2 - || info->endian < 0 || info->endian > 1) - MERROR (MERROR_CODING, -1); - } - else - return -1; - - MSTRUCT_CALLOC (spec, MERROR_CODING); - *spec = *info; - coding->extra_spec = (void *) (spec); - return 0; -} - -static int -reset_coding_utf (MConverter *converter) -{ - MConverterStatus *internal = (MConverterStatus *) converter->internal_info; - MCodingSystem *coding = internal->coding; - struct utf_status *status = (struct utf_status *) &(converter->status); - - if (! coding->ready - && setup_coding_utf (coding) < 0) - return -1; - coding->ready = 1; - - status->surrogate = 0; - status->bom = ((MCodingInfoUTF *) (coding->extra_spec))->bom; - status->endian = ((MCodingInfoUTF *) (coding->extra_spec))->endian; - return 0; -} - -static int -decode_coding_utf_16 (unsigned char *source, int src_bytes, MText *mt, - MConverter *converter) -{ - MConverterStatus *internal = (MConverterStatus *) converter->internal_info; - unsigned char *src = internal->carryover; - unsigned char *src_stop = src + internal->carryover_bytes; - unsigned char *src_end = source + src_bytes; - unsigned char *src_base; - unsigned char *dst = mt->data + mt->nbytes; - unsigned char *dst_end = mt->data + mt->allocated; - int nchars = 0; - int last_nchars = 0; - int at_most = converter->at_most > 0 ? converter->at_most : -1; - struct utf_status *status = (struct utf_status *) &(converter->status); - unsigned char b1, b2; - MCharset *charset = NULL; - int error = 0; - - if (status->bom != UTF_BOM_NO) - { - int c; - - ONE_MORE_BASE_BYTE (b1); - ONE_MORE_BYTE (b2); - c = (b1 << 8) | b2; - if (c == 0xFEFF) - status->endian = UTF_BIG_ENDIAN; - else if (c == 0xFFFE) - status->endian = UTF_LITTLE_ENDIAN; - else if (status->bom == UTF_BOM_MAYBE - || converter->lenient) - { - status->endian = UTF_BIG_ENDIAN; - REWIND_SRC_TO_BASE (); - } - else - { - error = 1; - goto source_end; - } - status->bom = UTF_BOM_NO; - } - - while (1) - { - int c, c1; - MCharset *this_charset = NULL; - - ONE_MORE_BASE_BYTE (b1); - ONE_MORE_BYTE (b2); - if (status->endian == UTF_BIG_ENDIAN) - c = ((b1 << 8) | b2); - else - c = ((b2 << 8) | b1); - if (c < 0xD800 || c >= 0xE000) - goto emit_char; - else if (c < 0xDC00) - { - ONE_MORE_BYTE (b1); - ONE_MORE_BYTE (b2); - if (status->endian == UTF_BIG_ENDIAN) - c1 = ((b1 << 8) | b2); - else - c1 = ((b2 << 8) | b1); - if (c1 < 0xDC00 || c1 >= 0xE000) - goto invalid_byte; - c = 0x10000 + ((c - 0xD800) << 10) + (c1 - 0xDC00); - goto emit_char; - } - - invalid_byte: - if (! converter->lenient) - break; - REWIND_SRC_TO_BASE (); - ONE_MORE_BYTE (b1); - ONE_MORE_BYTE (b2); - if (status->endian == UTF_BIG_ENDIAN) - c = ((b1 << 8) | b2); - else - c = ((b2 << 8) | b1); - this_charset = mcharset__binary; - - emit_char: - if (this_charset != charset) - { - TAKEIN_CHARS (mt, nchars - last_nchars, - dst - (mt->data + mt->nbytes), charset); - charset = this_charset; - last_nchars = nchars; - } - EMIT_CHAR (c); - } - /* We reach here because of an invalid byte. */ - error = 1; - - source_end: - TAKEIN_CHARS (mt, nchars - last_nchars, - dst - (mt->data + mt->nbytes), charset); - return finish_decoding (mt, converter, nchars, - source, src_end, src_base, error); -} - - -static int -decode_coding_utf_32 (unsigned char *source, int src_bytes, MText *mt, - MConverter *converter) -{ - MConverterStatus *internal = (MConverterStatus *) converter->internal_info; - unsigned char *src = internal->carryover; - unsigned char *src_stop = src + internal->carryover_bytes; - unsigned char *src_end = source + src_bytes; - unsigned char *src_base; - unsigned char *dst = mt->data + mt->nbytes; - unsigned char *dst_end = mt->data + mt->allocated; - int nchars = 0; - int last_nchars = 0; - int at_most = converter->at_most > 0 ? converter->at_most : -1; - struct utf_status *status = (struct utf_status *) &(converter->status); - unsigned char b1, b2, b3, b4; - MCharset *charset = NULL; - int error = 0; - - if (status->bom != UTF_BOM_NO) - { - unsigned c; - - ONE_MORE_BASE_BYTE (b1); - ONE_MORE_BYTE (b2); - ONE_MORE_BYTE (b3); - ONE_MORE_BYTE (b4); - c = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4; - if (c == 0x0000FEFF) - status->endian = UTF_BIG_ENDIAN; - else if (c == 0xFFFE0000) - status->endian = UTF_LITTLE_ENDIAN; - else if (status->bom == UTF_BOM_MAYBE - || converter->lenient) - { - status->endian = UTF_BIG_ENDIAN; - REWIND_SRC_TO_BASE (); - } - else - { - error = 1; - goto source_end; - } - status->bom = UTF_BOM_NO; - } - - while (1) - { - unsigned c; - MCharset *this_charset = NULL; - - ONE_MORE_BASE_BYTE (b1); - ONE_MORE_BYTE (b2); - ONE_MORE_BYTE (b3); - ONE_MORE_BYTE (b4); - if (status->endian == UTF_BIG_ENDIAN) - c = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4; - else - c = (b4 << 24) | (b3 << 16) | (b2 << 8) | b1; - if (c < 0xD800 || (c >= 0xE000 && c < 0x110000)) - goto emit_char; - - if (! converter->lenient) - break; - REWIND_SRC_TO_BASE (); - ONE_MORE_BYTE (c); - this_charset = mcharset__binary; - - emit_char: - if (this_charset != charset) - { - TAKEIN_CHARS (mt, nchars - last_nchars, - dst - (mt->data + mt->nbytes), charset); - charset = this_charset; - last_nchars = nchars; - } - EMIT_CHAR (c); - } - /* We reach here because of an invalid byte. */ - error = 1; - - source_end: - TAKEIN_CHARS (mt, nchars - last_nchars, - dst - (mt->data + mt->nbytes), charset); - return finish_decoding (mt, converter, nchars, - source, src_end, src_base, error); -} - - -static int -encode_coding_utf_16 (MText *mt, int from, int to, - unsigned char *destination, int dst_bytes, - MConverter *converter) -{ - unsigned char *src, *src_end; - unsigned char *dst = destination; - unsigned char *dst_end = dst + dst_bytes; - int nchars = 0; - struct utf_status *status = (struct utf_status *) &(converter->status); - int big_endian = status->endian == UTF_BIG_ENDIAN; - enum MTextFormat format = mt->format; - - SET_SRC (mt, format, from, to); - - if (status->bom != UTF_BOM_NO) - { - CHECK_DST (2); - if (big_endian) - *dst++ = 0xFE, *dst++ = 0xFF; - else - *dst++ = 0xFF, *dst++ = 0xFE; - status->bom = UTF_BOM_NO; - } - - while (1) - { - int c, bytes; - - ONE_MORE_CHAR (c, bytes, format); - - if (c < 0xD800 || (c >= 0xE000 && c < 0x10000)) - { - CHECK_DST (2); - if (big_endian) - *dst++ = c >> 8, *dst++ = c & 0xFF; - else - *dst++ = c & 0xFF, *dst++ = c >> 8; - } - else if (c >= 0x10000 && c < 0x110000) - { - int c1, c2; - - CHECK_DST (4); - c -= 0x10000; - c1 = (c >> 10) + 0xD800; - c2 = (c & 0x3FF) + 0xDC00; - if (big_endian) - *dst++ = c1 >> 8, *dst++ = c1 & 0xFF, - *dst++ = c2 >> 8, *dst++ = c2 & 0xFF; - else - *dst++ = c1 & 0xFF, *dst++ = c1 >> 8, - *dst++ = c2 & 0xFF, *dst++ = c2 >> 8; - } - else - { - unsigned char buf[11]; - int len, i; - - if (! converter->lenient) - break; - len = encode_unsupporeted_char (c, buf, buf + (dst_end - dst), - mt, from + nchars); - if (len == 0) - goto insufficient_destination; - if (big_endian) - for (i = 0; i < len; i++) - *dst++ = 0, *dst++ = buf[i]; - else - for (i = 0; i < len; i++) - *dst++ = buf[i], *dst++ = 0; - } - src += bytes; - nchars++; - } - /* We reach here because of an unsupported char. */ - converter->result = MCONVERSION_RESULT_INVALID_CHAR; - goto finish; - - insufficient_destination: - converter->result = MCONVERSION_RESULT_INSUFFICIENT_DST; - - finish: - converter->nchars += nchars; - converter->nbytes += dst - destination; - return (converter->result == MCONVERSION_RESULT_INVALID_CHAR ? -1 : 0); -} - -static int -encode_coding_utf_32 (MText *mt, int from, int to, - unsigned char *destination, int dst_bytes, - MConverter *converter) -{ - unsigned char *src, *src_end; - unsigned char *dst = destination; - unsigned char *dst_end = dst + dst_bytes; - int nchars = 0; - struct utf_status *status = (struct utf_status *) &(converter->status); - int big_endian = status->endian == UTF_BIG_ENDIAN; - enum MTextFormat format = mt->format; - - SET_SRC (mt, format, from, to); - - if (status->bom != UTF_BOM_NO) - { - CHECK_DST (4); - if (big_endian) - *dst++ = 0x00, *dst++ = 0x00, *dst++ = 0xFE, *dst++ = 0xFF; - else - *dst++ = 0xFF, *dst++ = 0xFE, *dst++ = 0x00, *dst++ = 0x00; - status->bom = UTF_BOM_NO; - } - - while (1) - { - int c, bytes; - - ONE_MORE_CHAR (c, bytes, format); - - if (c < 0xD800 || (c >= 0xE000 && c < 0x110000)) - { - CHECK_DST (4); - if (big_endian) - *dst++ = 0x00, *dst++ = c >> 16, - *dst++ = (c >> 8) & 0xFF, *dst++ = c & 0xFF; - else - *dst++ = c & 0xFF, *dst++ = (c >> 8) & 0xFF, - *dst++ = c >> 16, *dst++ = 0x00; - } - else - { - unsigned char buf[11]; - int len, i; - - if (! converter->lenient) - break; - len = encode_unsupporeted_char (c, buf, buf + (dst_end - dst), - mt, from + nchars); - if (len == 0) - goto insufficient_destination; - if (big_endian) - for (i = 0; i < len; i++) - *dst++ = 0, *dst++ = buf[i]; - else - for (i = 0; i < len; i++) - *dst++ = buf[i], *dst++ = 0; - } - src += bytes; - nchars++; - } - /* We reach here because of an unsupported char. */ - converter->result = MCONVERSION_RESULT_INVALID_CHAR; - goto finish; - - insufficient_destination: - converter->result = MCONVERSION_RESULT_INSUFFICIENT_DST; - - finish: - converter->nchars += nchars; - converter->nbytes += dst - destination; - return (converter->result == MCONVERSION_RESULT_INVALID_CHAR ? -1 : 0); -} - - -/* Staffs for coding-systems of type MCODING_TYPE_ISO_2022. */ - -#define ISO_CODE_STX 0x02 /* start text */ -#define ISO_CODE_SO 0x0E /* shift-out */ -#define ISO_CODE_SI 0x0F /* shift-in */ -#define ISO_CODE_SS2_7 0x19 /* single-shift-2 for 7-bit code */ -#define ISO_CODE_ESC 0x1B /* escape */ -#define ISO_CODE_SS2 0x8E /* single-shift-2 */ -#define ISO_CODE_SS3 0x8F /* single-shift-3 */ - -/** Structure pointed by MCodingSystem.extra_spec. */ - -struct iso_2022_spec -{ - unsigned flags; - - /** Initial graphic registers (0..3) invoked to each graphic - plane left and right. */ - int initial_invocation[2]; - - /** Initially designated charsets for each graphic register. */ - MCharset *initial_designation[4]; - - int n_designations; - char *designations; - - int use_esc; -}; - -struct iso_2022_status -{ - int invocation[2]; - MCharset *designation[4]; - unsigned single_shifting : 1; - unsigned bol : 1; - unsigned r2l : 1; - unsigned utf8_shifting : 1; - MCharset *non_standard_charset; - int non_standard_charset_bytes; - int non_standard_encoding; -}; - -enum iso_2022_code_class { - ISO_control_0, /* Control codes in the range - 0x00..0x1F and 0x7F, except for the - following 4 codes. */ - ISO_shift_out, /* ISO_CODE_SO (0x0E) */ - ISO_shift_in, /* ISO_CODE_SI (0x0F) */ - ISO_single_shift_2_7, /* ISO_CODE_SS2_7 (0x19) */ - ISO_escape, /* ISO_CODE_SO (0x1B) */ - ISO_control_1, /* Control codes in the range - 0x80..0x9F, except for the - following 3 codes. */ - ISO_single_shift_2, /* ISO_CODE_SS2 (0x8E) */ - ISO_single_shift_3, /* ISO_CODE_SS3 (0x8F) */ - ISO_control_sequence_introducer, /* ISO_CODE_CSI (0x9B) */ - ISO_0x20_or_0x7F, /* Codes of the values 0x20 or 0x7F. */ - ISO_graphic_plane_0, /* Graphic codes in the range 0x21..0x7E. */ - ISO_0xA0_or_0xFF, /* Codes of the values 0xA0 or 0xFF. */ - ISO_graphic_plane_1 /* Graphic codes in the range 0xA1..0xFE. */ -} iso_2022_code_class[256]; - - -#define MCODING_ISO_DESIGNATION_MASK \ - (MCODING_ISO_DESIGNATION_G0 \ - | MCODING_ISO_DESIGNATION_G1 \ - | MCODING_ISO_DESIGNATION_CTEXT \ - | MCODING_ISO_DESIGNATION_CTEXT_EXT) - -static int -setup_coding_iso_2022 (MCodingSystem *coding) -{ - MCodingInfoISO2022 *info = (MCodingInfoISO2022 *) (coding->extra_info); - int ncharsets = coding->ncharsets; - struct iso_2022_spec *spec; - int designation_policy = info->flags & MCODING_ISO_DESIGNATION_MASK; - int i; - - coding->ascii_compatible = 0; - - MSTRUCT_CALLOC (spec, MERROR_CODING); - - spec->flags = info->flags; - spec->initial_invocation[0] = info->initial_invocation[0]; - spec->initial_invocation[1] = info->initial_invocation[1]; - for (i = 0; i < 4; i++) - spec->initial_designation[i] = NULL; - if (designation_policy) - { - spec->n_designations = ncharsets; - if (spec->flags & MCODING_ISO_FULL_SUPPORT) - spec->n_designations += mcharset__iso_2022_table.used; - MTABLE_CALLOC (spec->designations, spec->n_designations, MERROR_CODING); - for (i = 0; i < spec->n_designations; i++) - spec->designations[i] = -1; - } - else - { - if (spec->flags & MCODING_ISO_FULL_SUPPORT) - MERROR (MERROR_CODING, -1); - spec->designations = NULL; - } - - for (i = 0; i < ncharsets; i++) - { - int reg = info->designations[i]; - - if (reg != -5 - && coding->charsets[i]->final_byte > 0 - && (reg < -4 || reg > 3)) - MERROR (MERROR_CODING, -1); - if (reg >= 0) - { - if (spec->initial_designation[reg]) - MERROR (MERROR_CODING, -1); - spec->initial_designation[reg] = coding->charsets[i]; - } - else if (reg >= -4) - { - if (! designation_policy - && ! (spec->flags & MCODING_ISO_EUC_TW_SHIFT)) - MERROR (MERROR_CODING, -1); - reg += 4; - } - - if (designation_policy) - spec->designations[i] = reg; - if (coding->charsets[i] == mcharset__ascii) - coding->ascii_compatible = 1; - } - - if (coding->ascii_compatible - && (spec->flags & (MCODING_ISO_DESIGNATION_G0 - | MCODING_ISO_DESIGNATION_CTEXT - | MCODING_ISO_DESIGNATION_CTEXT_EXT - | MCODING_ISO_LOCKING_SHIFT))) - coding->ascii_compatible = 0; - - if (spec->flags & MCODING_ISO_FULL_SUPPORT) - for (i = 0; i < mcharset__iso_2022_table.used; i++) - { - MCharset *charset = mcharset__iso_2022_table.charsets[i]; - - spec->designations[ncharsets + i] - = ((designation_policy == MCODING_ISO_DESIGNATION_CTEXT - || designation_policy == MCODING_ISO_DESIGNATION_CTEXT_EXT) - ? (charset->code_range[0] == 32 - || charset->code_range[1] == 255) - : designation_policy == MCODING_ISO_DESIGNATION_G1); - } - - spec->use_esc = ((spec->flags & MCODING_ISO_DESIGNATION_MASK) - || ((spec->flags & MCODING_ISO_LOCKING_SHIFT) - && (spec->initial_designation[2] - || spec->initial_designation[3])) - || (! (spec->flags & MCODING_ISO_EIGHT_BIT) - && (spec->flags & MCODING_ISO_SINGLE_SHIFT)) - || (spec->flags & MCODING_ISO_ISO6429)); - - coding->extra_spec = (void *) spec; - - return 0; -} - -static int -reset_coding_iso_2022 (MConverter *converter) -{ - MConverterStatus *internal = (MConverterStatus *) converter->internal_info; - MCodingSystem *coding = internal->coding; - struct iso_2022_status *status - = (struct iso_2022_status *) &(converter->status); - struct iso_2022_spec *spec; - int i; - - if (! coding->ready - && setup_coding_iso_2022 (coding) < 0) - return -1; - coding->ready = 1; - - spec = (struct iso_2022_spec *) coding->extra_spec; - status->invocation[0] = spec->initial_invocation[0]; - status->invocation[1] = spec->initial_invocation[1]; - for (i = 0; i < 4; i++) - status->designation[i] = spec->initial_designation[i]; - status->single_shifting = 0; - status->bol = 1; - status->r2l = 0; - - return 0; -} - -#define ISO2022_DECODE_DESIGNATION(reg, dim, chars, final, rev) \ - do { \ - MCharset *charset; \ - \ - if ((final) < '0' || (final) >= 128) \ - goto invalid_byte; \ - if (rev < 0) \ - { \ - charset = MCHARSET_ISO_2022 ((dim), (chars), (final)); \ - if (! (spec->flags & MCODING_ISO_FULL_SUPPORT)) \ - { \ - int i; \ - \ - for (i = 0; i < coding->ncharsets; i++) \ - if (charset == coding->charsets[i]) \ - break; \ - if (i == coding->ncharsets) \ - goto invalid_byte; \ - } \ - } \ - else \ - { \ - int i; \ - \ - for (i = 0; i < mcharset__iso_2022_table.used; i++) \ - { \ - charset = mcharset__iso_2022_table.charsets[i]; \ - if (charset->revision == (rev) \ - && charset->dimension == (dim) \ - && charset->final_byte == (final) \ - && (charset->code_range[1] == (chars) \ - || ((chars) == 96 && charset->code_range[1] == 255))) \ - break; \ - } \ - if (i == mcharset__iso_2022_table.used) \ - goto invalid_byte; \ - } \ - status->designation[reg] = charset; \ - } while (0) - - -static MCharset * -find_ctext_non_standard_charset (char *charset_name) -{ - MCharset *charset; - - if (! strcmp (charset_name, "koi8-r")) - charset = MCHARSET (msymbol ("koi8-r")); - else if (! strcmp (charset_name, "big5-0")) - charset = MCHARSET (msymbol ("big5")); - else - charset = NULL; - return charset; -} - -static int -decode_coding_iso_2022 (unsigned char *source, int src_bytes, MText *mt, - MConverter *converter) -{ - MConverterStatus *internal = (MConverterStatus *) converter->internal_info; - MCodingSystem *coding = internal->coding; - unsigned char *src = internal->carryover; - unsigned char *src_stop = src + internal->carryover_bytes; - unsigned char *src_end = source + src_bytes; - unsigned char *src_base; - unsigned char *dst = mt->data + mt->nbytes; - unsigned char *dst_end = mt->data + mt->allocated; - int nchars = 0; - int last_nchars = 0; - int at_most = converter->at_most > 0 ? converter->at_most : -1; - struct iso_2022_spec *spec = (struct iso_2022_spec *) coding->extra_spec; - struct iso_2022_status *status - = (struct iso_2022_status *) &(converter->status); - MCharset *charset0, *charset1, *charset; - int error = 0; - MCharset *cns_charsets[15]; - - charset0 = (status->invocation[0] >= 0 - ? status->designation[status->invocation[0]] : NULL); - charset1 = (status->invocation[1] >= 0 - ? status->designation[status->invocation[1]] : NULL); - charset = mcharset__ascii; - - if (spec->flags & MCODING_ISO_EUC_TW_SHIFT) - { - int i; - - memset (cns_charsets, 0, sizeof (cns_charsets)); - for (i = 0; i < coding->ncharsets; i++) - if (coding->charsets[i]->dimension == 2 - && coding->charsets[i]->code_range[1] == 126) - { - int final = coding->charsets[i]->final_byte; - - if (final >= 'G' && final <= 'M') - cns_charsets[final - 'G'] = coding->charsets[i]; - else if (final < 0) - cns_charsets[14] = coding->charsets[i]; - } - } - - while (1) - { - MCharset *this_charset = NULL; - int c1, c2, c3; - - ONE_MORE_BASE_BYTE (c1); - - if (status->utf8_shifting) - { - int buf[6]; - int bytes = CHAR_BYTES_BY_HEAD (c1); - int i; - - buf[0] = c1; - for (i = 1; i < bytes; i++) - { - ONE_MORE_BYTE (c1); - buf[i] = c1; - } - this_charset = UTF8_CHARSET (buf); - c1 = STRING_CHAR_UTF8 (buf); - goto emit_char; - } - - if (status->non_standard_encoding > 0) - { - int i; - - this_charset = status->non_standard_charset; - for (i = 1; i < status->non_standard_charset_bytes; i++) - { - ONE_MORE_BYTE (c2); - c1 = (c1 << 8) | c2; - } - c1 = DECODE_CHAR (this_charset, c1); - goto emit_char; - } - - switch (iso_2022_code_class[c1]) - { - case ISO_graphic_plane_0: - this_charset = charset0; - break; - - case ISO_0x20_or_0x7F: - if (! charset0 - || (charset0->code_range[0] != 32 - && charset0->code_range[1] != 255)) - /* This is SPACE or DEL. */ - this_charset = mcharset__ascii; - else - /* This is a graphic character of plane 0. */ - this_charset = charset0; - break; - - case ISO_graphic_plane_1: - if (!charset1) - goto invalid_byte; - this_charset = charset1; - break; - - case ISO_0xA0_or_0xFF: - if (! charset1 - || charset1->code_range[0] == 33 - || ! (spec->flags & MCODING_ISO_EIGHT_BIT)) - goto invalid_byte; - /* This is a graphic character of plane 1. */ - if (! charset1) - goto invalid_byte; - this_charset = charset1; - break; - - case ISO_control_0: - this_charset = mcharset__ascii; - break; - - case ISO_control_1: - goto invalid_byte; - - case ISO_shift_out: - if ((spec->flags & MCODING_ISO_LOCKING_SHIFT) - && status->designation[1]) - { - status->invocation[0] = 1; - charset0 = status->designation[1]; - continue; - } - this_charset = mcharset__ascii; - break; - - case ISO_shift_in: - if (spec->flags & MCODING_ISO_LOCKING_SHIFT) - { - status->invocation[0] = 0; - charset0 = status->designation[0]; - continue; - } - this_charset = mcharset__ascii; - break; - - case ISO_single_shift_2_7: - if (! (spec->flags & MCODING_ISO_SINGLE_SHIFT_7)) - { - this_charset = mcharset__ascii; - break; - } - c1 = 'N'; - goto label_escape_sequence; - - case ISO_single_shift_2: - if (spec->flags & MCODING_ISO_EUC_TW_SHIFT) - { - ONE_MORE_BYTE (c1); - if (c1 < 0xA1 || (c1 > 0xA7 && c1 < 0xAF) || c1 > 0xAF - || ! cns_charsets[c1 - 0xA1]) - goto invalid_byte; - status->designation[2] = cns_charsets[c1 - 0xA1]; - } - else if (! (spec->flags & MCODING_ISO_SINGLE_SHIFT)) - goto invalid_byte; - /* SS2 is handled as an escape sequence of ESC 'N' */ - c1 = 'N'; - goto label_escape_sequence; - - case ISO_single_shift_3: - if (! (spec->flags & MCODING_ISO_SINGLE_SHIFT)) - goto invalid_byte; - /* SS2 is handled as an escape sequence of ESC 'O' */ - c1 = 'O'; - goto label_escape_sequence; - - case ISO_control_sequence_introducer: - /* CSI is handled as an escape sequence of ESC '[' ... */ - c1 = '['; - goto label_escape_sequence; - - case ISO_escape: - if (! spec->use_esc) - { - this_charset = mcharset__ascii; - break; - } - ONE_MORE_BYTE (c1); - label_escape_sequence: - /* Escape sequences handled here are invocation, - designation, and direction specification. */ - switch (c1) - { - case '&': /* revision of following character set */ - if (! (spec->flags & MCODING_ISO_DESIGNATION_MASK)) - goto unused_escape_sequence; - ONE_MORE_BYTE (c1); - if (c1 < '@' || c1 > '~') - goto invalid_byte; - ONE_MORE_BYTE (c1); - if (c1 != ISO_CODE_ESC) - goto invalid_byte; - ONE_MORE_BYTE (c1); - goto label_escape_sequence; - - case '$': /* designation of 2-byte character set */ - if (! (spec->flags & MCODING_ISO_DESIGNATION_MASK)) - goto unused_escape_sequence; - ONE_MORE_BYTE (c1); - if (c1 >= '@' && c1 <= 'B') - { /* designation of JISX0208.1978, GB2312.1980, or - JISX0208.1980 */ - ISO2022_DECODE_DESIGNATION (0, 2, 94, c1, -1); - } - else if (c1 >= 0x28 && c1 <= 0x2B) - { /* designation of (dimension 2, chars 94) character set */ - ONE_MORE_BYTE (c2); - ISO2022_DECODE_DESIGNATION (c1 - 0x28, 2, 94, c2, -1); - } - else if (c1 >= 0x2C && c1 <= 0x2F) - { /* designation of (dimension 2, chars 96) character set */ - ONE_MORE_BYTE (c2); - ISO2022_DECODE_DESIGNATION (c1 - 0x2C, 2, 96, c2, -1); - } - else - goto invalid_byte; - /* We must update these variables now. */ - charset0 = status->designation[status->invocation[0]]; - charset1 = status->designation[status->invocation[1]]; - continue; - - case 'n': /* invocation of locking-shift-2 */ - if (! (spec->flags & MCODING_ISO_LOCKING_SHIFT) - || ! status->designation[2]) - goto invalid_byte; - status->invocation[0] = 2; - charset0 = status->designation[2]; - continue; - - case 'o': /* invocation of locking-shift-3 */ - if (! (spec->flags & MCODING_ISO_LOCKING_SHIFT) - || ! status->designation[3]) - goto invalid_byte; - status->invocation[0] = 3; - charset0 = status->designation[3]; - continue; - - case 'N': /* invocation of single-shift-2 */ - if (! ((spec->flags & MCODING_ISO_SINGLE_SHIFT) - || (spec->flags & MCODING_ISO_EUC_TW_SHIFT)) - || ! status->designation[2]) - goto invalid_byte; - this_charset = status->designation[2]; - ONE_MORE_BYTE (c1); - if (c1 < 0x20 || (c1 >= 0x80 && c1 < 0xA0)) - goto invalid_byte; - break; - - case 'O': /* invocation of single-shift-3 */ - if (! (spec->flags & MCODING_ISO_SINGLE_SHIFT) - || ! status->designation[3]) - goto invalid_byte; - this_charset = status->designation[3]; - ONE_MORE_BYTE (c1); - if (c1 < 0x20 || (c1 >= 0x80 && c1 < 0xA0)) - goto invalid_byte; - break; - - case '[': /* specification of direction */ - if (! (spec->flags & MCODING_ISO_ISO6429)) - goto invalid_byte; - /* For the moment, nested direction is not supported. - So, (coding->mode & CODING_MODE_DIRECTION) zero means - left-to-right, and nonzero means right-to-left. */ - ONE_MORE_BYTE (c1); - switch (c1) - { - case ']': /* end of the current direction */ - case '0': /* end of the current direction */ - status->r2l = 0; - break; - - case '1': /* start of left-to-right direction */ - ONE_MORE_BYTE (c1); - if (c1 != ']') - goto invalid_byte; - status->r2l = 0; - break; - - case '2': /* start of right-to-left direction */ - ONE_MORE_BYTE (c1); - if (c1 != ']') - goto invalid_byte; - status->r2l = 1; - break; - - default: - goto invalid_byte; - } - continue; - - case '%': - { - char charset_name[16]; - int bytes; - int i; - - if (! spec->flags & MCODING_ISO_DESIGNATION_CTEXT_EXT) - goto invalid_byte; - /* Compound-text uses these escape sequences: - - ESC % G -- utf-8 bytes -- ESC % @ - ESC % / 1 M L -- charset name -- STX -- bytes -- - ESC % / 2 M L -- charset name -- STX -- bytes -- - ESC % / 3 M L -- charset name -- STX -- bytes -- - ESC % / 4 M L -- charset name -- STX -- bytes -- - - It also uses this sequence but that is not yet - supported here. - - ESC % / 0 M L -- charset name -- STX -- bytes -- */ - - ONE_MORE_BYTE (c1); - if (c1 == 'G') - { - status->utf8_shifting = 1; - continue; - } - if (c1 == '@') - { - if (! status->utf8_shifting) - goto invalid_byte; - status->utf8_shifting = 0; - continue; - } - if (c1 != '/') - goto invalid_byte; - ONE_MORE_BYTE (c1); - if (c1 < '1' || c1 > '4') - goto invalid_byte; - status->non_standard_charset_bytes = c1 - '0'; - ONE_MORE_BYTE (c1); - ONE_MORE_BYTE (c2); - if (c1 < 128 || c2 < 128) - goto invalid_byte; - bytes = (c1 - 128) * 128 + (c2 - 128); - for (i = 0; i < 16; i++) - { - ONE_MORE_BYTE (c1); - if (c1 == ISO_CODE_STX) - break; - charset_name[i] = TOLOWER (c1); - } - if (i == 16) - goto invalid_byte; - charset_name[i++] = '\0'; - this_charset = find_ctext_non_standard_charset (charset_name); - if (! this_charset) - goto invalid_byte; - status->non_standard_charset = this_charset; - status->non_standard_encoding = bytes - i; - continue; - } - - default: - if (! (spec->flags & MCODING_ISO_DESIGNATION_MASK)) - goto unused_escape_sequence; - if (c1 >= 0x28 && c1 <= 0x2B) - { /* designation of (dimension 1, chars 94) charset */ - ONE_MORE_BYTE (c2); - ISO2022_DECODE_DESIGNATION (c1 - 0x28, 1, 94, c2, -1); - } - else if (c1 >= 0x2C && c1 <= 0x2F) - { /* designation of (dimension 1, chars 96) charset */ - ONE_MORE_BYTE (c2); - ISO2022_DECODE_DESIGNATION (c1 - 0x2C, 1, 96, c2, -1); - } - else - goto invalid_byte; - /* We must update these variables now. */ - charset0 = status->designation[status->invocation[0]]; - charset1 = status->designation[status->invocation[1]]; - continue; - - unused_escape_sequence: - UNGET_ONE_BYTE (c1); - c1 = ISO_CODE_ESC; - this_charset = mcharset__ascii; - } - } - - if (this_charset->dimension == 1) - { - if (this_charset->code_range[1] <= 128) - c1 &= 0x7F; - } - else if (this_charset->dimension == 2) - { - ONE_MORE_BYTE (c2); - c1 = ((c1 & 0x7F) << 8) | (c2 & 0x7F); - } - else /* i.e. (dimension == 3) */ - { - ONE_MORE_BYTE (c2); - ONE_MORE_BYTE (c3); - c1 = ((c1 & 0x7F) << 16) | ((c2 & 0x7F) << 8) | (c3 & 0x7F); - } - c1 = DECODE_CHAR (this_charset, c1); - goto emit_char; - - invalid_byte: - if (! converter->lenient) - break; - REWIND_SRC_TO_BASE (); - c1 = *src++; - this_charset = mcharset__binary; - - emit_char: - if (this_charset != mcharset__ascii - && this_charset != charset) - { - TAKEIN_CHARS (mt, nchars - last_nchars, - dst - (mt->data + mt->nbytes), charset); - charset = this_charset; - last_nchars = nchars; - } - EMIT_CHAR (c1); - if (status->non_standard_encoding > 0) - status->non_standard_encoding -= status->non_standard_charset_bytes; - } - /* We reach here because of an invalid byte. */ - error = 1; - - - - source_end: - TAKEIN_CHARS (mt, nchars - last_nchars, - dst - (mt->data + mt->nbytes), charset); - return finish_decoding (mt, converter, nchars, - source, src_end, src_base, error); - -} - -/* Produce codes (escape sequence) for designating CHARSET to graphic - register REG at DST, and increment DST. If CHARSET->final-char is - '@', 'A', or 'B' and SHORT_FORM is nonzero, produce designation - sequence of short-form. Update STATUS->designation. */ - -#define ISO2022_ENCODE_DESIGNATION(reg, charset, spec, status) \ - do { \ - char *intermediate_char_94 = "()*+"; \ - char *intermediate_char_96 = ",-./"; \ - \ - if (dst + 4 > dst_end) \ - goto memory_shortage; \ - *dst++ = ISO_CODE_ESC; \ - if (charset->dimension == 1) \ - { \ - if (charset->code_range[0] != 32 \ - && charset->code_range[1] != 255) \ - *dst++ = (unsigned char) (intermediate_char_94[reg]); \ - else \ - *dst++ = (unsigned char) (intermediate_char_96[reg]); \ - } \ - else \ - { \ - *dst++ = '$'; \ - if (charset->code_range[0] != 32 \ - && charset->code_range[1] != 255) \ - { \ - if (spec->flags & MCODING_ISO_LONG_FORM \ - || reg != 0 \ - || charset->final_byte < '@' || charset->final_byte > 'B') \ - *dst++ = (unsigned char) (intermediate_char_94[reg]); \ - } \ - else \ - *dst++ = (unsigned char) (intermediate_char_96[reg]); \ - } \ - *dst++ = charset->final_byte; \ - \ - status->designation[reg] = charset; \ - } while (0) - - -/* The following two macros produce codes (control character or escape - sequence) for ISO-2022 single-shift functions (single-shift-2 and - single-shift-3). */ - -#define ISO2022_ENCODE_SINGLE_SHIFT_2(spec, status) \ - do { \ - if (dst + 2 > dst_end) \ - goto memory_shortage; \ - if (! (spec->flags & MCODING_ISO_EIGHT_BIT)) \ - *dst++ = ISO_CODE_ESC, *dst++ = 'N'; \ - else \ - *dst++ = ISO_CODE_SS2; \ - status->single_shifting = 1; \ - } while (0) - - -#define ISO2022_ENCODE_SINGLE_SHIFT_3(spec, status) \ - do { \ - if (dst + 2 > dst_end) \ - goto memory_shortage; \ - if (! (spec->flags & MCODING_ISO_EIGHT_BIT)) \ - *dst++ = ISO_CODE_ESC, *dst++ = 'O'; \ - else \ - *dst++ = ISO_CODE_SS3; \ - status->single_shifting = 1; \ - } while (0) - - -/* The following four macros produce codes (control character or - escape sequence) for ISO-2022 locking-shift functions (shift-in, - shift-out, locking-shift-2, and locking-shift-3). */ - -#define ISO2022_ENCODE_SHIFT_IN(status) \ - do { \ - if (dst + 1 > dst_end) \ - goto memory_shortage; \ - *dst++ = ISO_CODE_SI; \ - status->invocation[0] = 0; \ - } while (0) - - -#define ISO2022_ENCODE_SHIFT_OUT(status) \ - do { \ - if (dst + 1 > dst_end) \ - goto memory_shortage; \ - *dst++ = ISO_CODE_SO; \ - status->invocation[0] = 1; \ - } while (0) - - -#define ISO2022_ENCODE_LOCKING_SHIFT_2(status) \ - do { \ - if (dst + 2 > dst_end) \ - goto memory_shortage; \ - *dst++ = ISO_CODE_ESC, *dst++ = 'n'; \ - status->invocation[0] = 2; \ - } while (0) - - -#define ISO2022_ENCODE_LOCKING_SHIFT_3(status) \ - do { \ - if (dst + 2 > dst_end) \ - goto memory_shortage; \ - *dst++ = ISO_CODE_ESC, *dst++ = 'o'; \ - status->invocation[0] = 3; \ - } while (0) - -#define ISO2022_ENCODE_UTF8_SHIFT_START(len) \ - do { \ - CHECK_DST (3 + len); \ - *dst++ = ISO_CODE_ESC; \ - *dst++ = '%'; \ - *dst++ = 'G'; \ - status->utf8_shifting = 1; \ - } while (0) - - -#define ISO2022_ENCODE_UTF8_SHIFT_END() \ - do { \ - CHECK_DST (3); \ - *dst++ = ISO_CODE_ESC; \ - *dst++ = '%'; \ - *dst++ = '@'; \ - status->utf8_shifting = 0; \ - } while (0) - - -#define ISO2022_ENCODE_NON_STANDARD(name, len) \ - do { \ - CHECK_DST (6 + len + 1 + non_standard_charset_bytes); \ - non_standard_begin = dst; \ - *dst++ = ISO_CODE_ESC; \ - *dst++ = '%'; \ - *dst++ = '/'; \ - *dst++ = '0' + non_standard_charset_bytes; \ - *dst++ = 0, *dst++ = 0; /* filled later */ \ - memcpy (dst, name, len); \ - dst += len; \ - *dst++ = ISO_CODE_STX; \ - non_standard_bytes = len + 1; \ - } while (0) - - -static char * -find_ctext_non_standard_name (MCharset *charset, int *bytes) -{ - char *name = msymbol_name (charset->name); - - if (! strcmp (name, "koi8-r")) - *bytes = 1; - else if (! strcmp (name, "big5")) - name = "big5-0", *bytes = 2; - else - return NULL; - return name; -} - -/* Designate CHARSET to a graphic register specified in - SPEC->designation. If the register is not yet invoked to graphic - left not right, invoke it to graphic left. DSTP points to a - variable containing a memory address where the output must go. - DST_END is the limit of that memory. - - Return 0 if it succeeds. Return -1 otherwise, which means that the - memory area is too short. By side effect, update the variable that - DSTP points to. */ - -static int -iso_2022_designate_invoke_charset (MCodingSystem *coding, - MCharset *charset, - struct iso_2022_spec *spec, - struct iso_2022_status *status, - unsigned char **dstp, - unsigned char *dst_end) -{ - int i; - unsigned char *dst = *dstp; - - for (i = 0; i < 4; i++) - if (charset == status->designation[i]) - break; - - if (i >= 4) - { - /* CHARSET is not yet designated to any graphic registers. */ - for (i = 0; i < coding->ncharsets; i++) - if (charset == coding->charsets[i]) - break; - if (i == coding->ncharsets) - { - for (i = 0; i < mcharset__iso_2022_table.used; i++) - if (charset == mcharset__iso_2022_table.charsets[i]) - break; - i += coding->ncharsets; - } - i = spec->designations[i]; - ISO2022_ENCODE_DESIGNATION (i, charset, spec, status); - } - - if (status->invocation[0] != i - && status->invocation[1] != i) - { - /* Graphic register I is not yet invoked. */ - switch (i) - { - case 0: /* graphic register 0 */ - ISO2022_ENCODE_SHIFT_IN (status); - break; - - case 1: /* graphic register 1 */ - ISO2022_ENCODE_SHIFT_OUT (status); - break; - - case 2: /* graphic register 2 */ - if (spec->flags & MCODING_ISO_SINGLE_SHIFT) - ISO2022_ENCODE_SINGLE_SHIFT_2 (spec, status); - else - ISO2022_ENCODE_LOCKING_SHIFT_2 (status); - break; - - case 3: /* graphic register 3 */ - if (spec->flags & MCODING_ISO_SINGLE_SHIFT) - ISO2022_ENCODE_SINGLE_SHIFT_3 (spec, status); - else - ISO2022_ENCODE_LOCKING_SHIFT_3 (status); - break; - } - } - *dstp = dst; - return 0; - - memory_shortage: - *dstp = dst; - return -1; -} - - -/* Reset the invocation/designation status to the initial one. SPEC - and STATUS contain information about the current and initial - invocation /designation status respectively. DSTP points to a - variable containing a memory address where the output must go. - DST_END is the limit of that memory. - - Return 0 if it succeeds. Return -1 otherwise, which means that the - memory area is too short. By side effect, update the variable that - DSTP points to. */ - -static int -iso_2022_reset_invocation_designation (struct iso_2022_spec *spec, - struct iso_2022_status *status, - unsigned char **dstp, - unsigned char *dst_end) -{ - unsigned char *dst = *dstp; - int i; - - /* Reset the invocation status of GL. We have not yet supported GR - invocation. */ - if (status->invocation[0] != spec->initial_invocation[0] - && spec->initial_invocation[0] >= 0) - { - if (spec->initial_invocation[0] == 0) - ISO2022_ENCODE_SHIFT_IN (status); - else if (spec->initial_invocation[0] == 1) - ISO2022_ENCODE_SHIFT_OUT (status); - else if (spec->initial_invocation[0] == 2) - ISO2022_ENCODE_LOCKING_SHIFT_2 (status); - else /* i.e. spec->initial_invocation[0] == 3 */ - ISO2022_ENCODE_LOCKING_SHIFT_3 (status); - } - - /* Reset the designation status of G0..G3. */ - for (i = 0; i < 4; i++) - if (status->designation[i] != spec->initial_designation[i] - && spec->initial_designation[i]) - { - MCharset *charset = spec->initial_designation[i]; - - ISO2022_ENCODE_DESIGNATION (i, charset, spec, status); - } - - *dstp = dst; - return 0; - - memory_shortage: - *dstp = dst; - return -1; -} - - -static int -encode_coding_iso_2022 (MText *mt, int from, int to, - unsigned char *destination, int dst_bytes, - MConverter *converter) -{ - MConverterStatus *internal = (MConverterStatus *) converter->internal_info; - MCodingSystem *coding = internal->coding; - unsigned char *src, *src_end; - unsigned char *dst = destination; - unsigned char *dst_end = dst + dst_bytes; - int nchars = 0; - unsigned char *dst_base; - struct iso_2022_spec *spec = (struct iso_2022_spec *) coding->extra_spec; - int full_support = spec->flags & MCODING_ISO_FULL_SUPPORT; - struct iso_2022_status *status - = (struct iso_2022_status *) &(converter->status); - MCharset *primary, *charset0, *charset1; - int next_primary_change; - int ncharsets = coding->ncharsets; - MCharset **charsets = coding->charsets; - MCharset *cns_charsets[15]; - int ascii_compatible = coding->ascii_compatible; - MCharset *non_standard_charset = NULL; - int non_standard_charset_bytes = 0; - int non_standard_bytes = 0; - unsigned char *non_standard_begin = NULL; - enum MTextFormat format = mt->format; - - SET_SRC (mt, format, from, to); - - if (spec->flags & MCODING_ISO_EUC_TW_SHIFT) - { - int i; - - memset (cns_charsets, 0, sizeof (cns_charsets)); - for (i = 0; i < ncharsets; i++) - if (charsets[i]->dimension == 2) - { - int final = charsets[i]->final_byte; - - if (final >= 'G' && final <= 'M') - cns_charsets[final - 'G'] = charsets[i]; - else if (final < 0) - cns_charsets[14] = charsets[i]; - } - } - - next_primary_change = from; - primary = NULL; - charset0 = status->designation[status->invocation[0]]; - charset1 = (status->invocation[1] < 0 ? NULL - : status->designation[status->invocation[1]]); - - while (1) - { - int bytes, c; - - dst_base = dst; - ONE_MORE_CHAR (c, bytes, format); - - if (c < 128 && ascii_compatible) - { - if (status->utf8_shifting) - ISO2022_ENCODE_UTF8_SHIFT_END (); - CHECK_DST (1); - *dst++ = c; - } - else if (c <= 32 || c == 127) - { - if (status->utf8_shifting) - ISO2022_ENCODE_UTF8_SHIFT_END (); - if (spec->flags & MCODING_ISO_RESET_AT_CNTL - || (c == '\n' && spec->flags & MCODING_ISO_RESET_AT_EOL)) - { - if (iso_2022_reset_invocation_designation (spec, status, - &dst, dst_end) < 0) - goto insufficient_destination; - charset0 = status->designation[status->invocation[0]]; - charset1 = (status->invocation[1] < 0 ? NULL - : status->designation[status->invocation[1]]); - } - CHECK_DST (1); - *dst++ = c; - } - else - { - unsigned code = MCHAR_INVALID_CODE; - MCharset *charset = NULL; - int gr_mask; - int pos = from + nchars; - - if (pos >= next_primary_change) - { - MSymbol primary_charset - = (MSymbol) mtext_get_prop (mt, pos, Mcharset); - primary = MCHARSET (primary_charset); - if (primary && primary != mcharset__binary) - { - if (primary->final_byte <= 0) - primary = NULL; - else if (! full_support) - { - int i; - - for (i = 0; i < ncharsets; i++) - if (primary == charsets[i]) - break; - if (i == ncharsets) - primary = NULL; - } - } - - mtext_prop_range (mt, Mcharset, pos, - NULL, &next_primary_change, 0); - } - - if (primary && primary != mcharset__binary) - { - code = ENCODE_CHAR (primary, c); - if (code != MCHAR_INVALID_CODE) - charset = primary; - } - if (! charset) - { - if (c <= 32 || c == 127) - { - code = c; - charset = mcharset__ascii; - } - else - { - int i; - - for (i = 0; i < ncharsets; i++) - { - charset = charsets[i]; - code = ENCODE_CHAR (charset, c); - if (code != MCHAR_INVALID_CODE) - break; - } - if (i == ncharsets) - { - if (spec->flags & MCODING_ISO_FULL_SUPPORT) - { - for (i = 0; i < mcharset__iso_2022_table.used; i++) - { - charset = mcharset__iso_2022_table.charsets[i]; - code = ENCODE_CHAR (charset, c); - if (code != MCHAR_INVALID_CODE) - break; - } - if (i == mcharset__iso_2022_table.used) - { - if (spec->flags & MCODING_ISO_DESIGNATION_CTEXT_EXT) - goto unsupported_char; - converter->result = MCONVERSION_RESULT_INVALID_CHAR; - goto finish; - } - } - else - goto unsupported_char; - } - } - } - - if (charset - && (charset->final_byte >= 0 - || spec->flags & MCODING_ISO_EUC_TW_SHIFT)) - { - if (code >= 0x80 && code < 0xA0) - goto unsupported_char; - code &= 0x7F7F7F7F; - if (status->utf8_shifting) - ISO2022_ENCODE_UTF8_SHIFT_END (); - if (charset == charset0) - gr_mask = 0; - else if (charset == charset1) - gr_mask = 0x80; - else - { - unsigned char *p = NULL; - - if (spec->flags & MCODING_ISO_EUC_TW_SHIFT) - { - int i; - - if (cns_charsets[0] == charset) - { - CHECK_DST (2); - } - else - { - for (i = 1; i < 15; i++) - if (cns_charsets[i] == charset) - break; - CHECK_DST (4); - *dst++ = ISO_CODE_SS2; - *dst++ = 0xA1 + i; - } - status->single_shifting = 1; - p = dst; - } - else - { - if (iso_2022_designate_invoke_charset - (coding, charset, spec, status, &dst, dst_end) < 0) - goto insufficient_destination; - charset0 = status->designation[status->invocation[0]]; - charset1 = (status->invocation[1] < 0 ? NULL - : status->designation[status->invocation[1]]); - } - if (status->single_shifting) - gr_mask - = (spec->flags & MCODING_ISO_EIGHT_BIT) ? 0x80 : 0; - else if (charset == charset0) - gr_mask = 0; - else - gr_mask = 0x80; - } - if (charset->dimension == 1) - { - CHECK_DST (1); - *dst++ = code | gr_mask; - } - else if (charset->dimension == 2) - { - CHECK_DST (2); - *dst++ = (code >> 8) | gr_mask; - *dst++ = (code & 0xFF) | gr_mask; - } - else - { - CHECK_DST (3); - *dst++ = (code >> 16) | gr_mask; - *dst++ = ((code >> 8) & 0xFF) | gr_mask; - *dst++ = (code & 0xFF) | gr_mask; - } - status->single_shifting = 0; - } - else if (charset && spec->flags & MCODING_ISO_DESIGNATION_CTEXT_EXT) - { - if (charset != non_standard_charset) - { - char *name = (find_ctext_non_standard_name - (charset, &non_standard_charset_bytes)); - - if (name) - { - int len = strlen (name); - - ISO2022_ENCODE_NON_STANDARD (name, len); - non_standard_charset = charset; - } - else - non_standard_charset = NULL; - } - - if (non_standard_charset) - { - if (dst + non_standard_charset_bytes > dst_end) - goto insufficient_destination; - non_standard_bytes += non_standard_charset_bytes; - non_standard_begin[4] = (non_standard_bytes / 128) | 0x80; - non_standard_begin[5] = (non_standard_bytes % 128) | 0x80; - if (non_standard_charset_bytes == 1) - *dst++ = code; - else if (non_standard_charset_bytes == 2) - *dst++ = code >> 8, *dst++ = code & 0xFF; - else if (non_standard_charset_bytes == 3) - *dst++ = code >> 16, *dst++ = (code >> 8) & 0xFF, - *dst++ = code & 0xFF; - else /* i.e non_standard_charset_bytes == 3 */ - *dst++ = code >> 24, *dst++ = (code >> 16) & 0xFF, - *dst++ = (code >> 8) & 0xFF, *dst++ = code & 0xFF; - } - else - { - int len = CHAR_BYTES (c); - - if (c >= 0x110000) - goto unsupported_char; - if (! status->utf8_shifting) - ISO2022_ENCODE_UTF8_SHIFT_START (len); - else - CHECK_DST (len); - CHAR_STRING (c, dst); - } - } - else - goto unsupported_char; - } - src += bytes; - nchars++; - continue; - - unsupported_char: - { - int len; - - if (iso_2022_designate_invoke_charset (coding, mcharset__ascii, - spec, status, - &dst, dst_end) < 0) - goto insufficient_destination; - if (! converter->lenient) - break; - len = encode_unsupporeted_char (c, dst, dst_end, mt, from + nchars); - if (len == 0) - goto insufficient_destination; - dst += len; - src += bytes; - nchars++; - } - } - /* We reach here because of an unsupported char. */ - converter->result = MCONVERSION_RESULT_INVALID_CHAR; - goto finish; - - insufficient_destination: - dst = dst_base; - converter->result = MCONVERSION_RESULT_INSUFFICIENT_DST; - - finish: - if (converter->result == MCONVERSION_RESULT_SUCCESS - && converter->last_block) - { - if (status->utf8_shifting) - { - ISO2022_ENCODE_UTF8_SHIFT_END (); - dst_base = dst; - } - if (spec->flags & MCODING_ISO_RESET_AT_EOL - && charset0 != spec->initial_designation[0]) - { - if (iso_2022_reset_invocation_designation (spec, status, - &dst, dst_end) < 0) - goto insufficient_destination; - } - } - converter->nchars += nchars; - converter->nbytes += dst - destination; - return (converter->result == MCONVERSION_RESULT_INVALID_CHAR ? -1 : 0); -} - - -/* Staffs for coding-systems of type MCODING_TYPE_MISC. */ - -/* For SJIS handling... */ - -#define SJIS_TO_JIS(s1, s2) \ - (s2 >= 0x9F \ - ? (((s1 * 2 - (s1 >= 0xE0 ? 0x160 : 0xE0)) << 8) \ - | (s2 - 0x7E)) \ - : (((s1 * 2 - ((s1 >= 0xE0) ? 0x161 : 0xE1)) << 8) \ - | (s2 - ((s2 >= 0x7F) ? 0x20 : 0x1F)))) - -#define JIS_TO_SJIS(c1, c2) \ - ((c1 & 1) \ - ? (((c1 / 2 + ((c1 < 0x5F) ? 0x71 : 0xB1)) << 8) \ - | (c2 + ((c2 >= 0x60) ? 0x20 : 0x1F))) \ - : (((c1 / 2 + ((c1 < 0x5F) ? 0x70 : 0xB0)) << 8) \ - | (c2 + 0x7E))) - - -static int -reset_coding_sjis (MConverter *converter) -{ - MConverterStatus *internal = (MConverterStatus *) converter->internal_info; - MCodingSystem *coding = internal->coding; - - if (! coding->ready) - { - MSymbol kanji_sym = msymbol ("jisx0208.1983"); - MCharset *kanji = MCHARSET (kanji_sym); - MSymbol kana_sym = msymbol ("jisx0201-kana"); - MCharset *kana = MCHARSET (kana_sym); - - if (! kanji_sym || ! kana_sym) - return -1; - coding->ncharsets = 3; - coding->charsets[1] = kanji; - coding->charsets[2] = kana; - } - coding->ready = 1; - return 0; -} - -static int -decode_coding_sjis (unsigned char *source, int src_bytes, MText *mt, - MConverter *converter) -{ - MConverterStatus *internal = (MConverterStatus *) converter->internal_info; - MCodingSystem *coding = internal->coding; - unsigned char *src = internal->carryover; - unsigned char *src_stop = src + internal->carryover_bytes; - unsigned char *src_end = source + src_bytes; - unsigned char *src_base; - unsigned char *dst = mt->data + mt->nbytes; - unsigned char *dst_end = mt->data + mt->allocated - MAX_UTF8_CHAR_BYTES; - int nchars = 0; - int last_nchars = 0; - int at_most = converter->at_most > 0 ? converter->at_most : -1; - - MCharset *charset_roman = coding->charsets[0]; - MCharset *charset_kanji = coding->charsets[1]; - MCharset *charset_kana = coding->charsets[2]; - MCharset *charset = mcharset__ascii; - int error = 0; - - while (1) - { - MCharset *this_charset; - int c, c1, c2; - - ONE_MORE_BASE_BYTE (c1); - - c2 = -1; - if (c1 < 0x80) - { - this_charset = ((c1 <= 0x20 || c1 == 0x7F) - ? mcharset__ascii - : charset_roman); - } - else if ((c1 >= 0x81 && c1 <= 0x9F) || (c1 >= 0xE0 && c1 <= 0xEF)) - { - ONE_MORE_BYTE (c2); - if ((c2 >= 0x40 && c2 <= 0x7F) || (c2 >= 80 && c2 <= 0xFC)) - { - this_charset = charset_kanji; - c1 = SJIS_TO_JIS (c1, c2); - } - else - goto invalid_byte; - } - else if (c1 >= 0xA1 && c1 <= 0xDF) - { - this_charset = charset_kana; - c1 &= 0x7F; - } - else - goto invalid_byte; - - c = DECODE_CHAR (this_charset, c1); - if (c >= 0) - goto emit_char; - - invalid_byte: - if (! converter->lenient) - break; - REWIND_SRC_TO_BASE (); - c = *src++; - this_charset = mcharset__binary; - - emit_char: - if (this_charset != mcharset__ascii - && this_charset != charset) - { - TAKEIN_CHARS (mt, nchars - last_nchars, - dst - (mt->data + mt->nbytes), charset); - charset = this_charset; - last_nchars = nchars; - } - EMIT_CHAR (c); - } - /* We reach here because of an invalid byte. */ - error = 1; - - source_end: - TAKEIN_CHARS (mt, nchars - last_nchars, - dst - (mt->data + mt->nbytes), charset); - return finish_decoding (mt, converter, nchars, - source, src_end, src_base, error); -} - -static int -encode_coding_sjis (MText *mt, int from, int to, - unsigned char *destination, int dst_bytes, - MConverter *converter) -{ - MConverterStatus *internal = (MConverterStatus *) converter->internal_info; - MCodingSystem *coding = internal->coding; - unsigned char *src, *src_end; - unsigned char *dst = destination; - unsigned char *dst_end = dst + dst_bytes; - int nchars = 0; - MCharset *charset_roman = coding->charsets[0]; - MCharset *charset_kanji = coding->charsets[1]; - MCharset *charset_kana = coding->charsets[2]; - enum MTextFormat format = mt->format; - - SET_SRC (mt, format, from, to); - - while (1) - { - int c, bytes, len; - unsigned code; - - ONE_MORE_CHAR (c, bytes, format); - - if (c <= 0x20 || c == 0x7F) - { - CHECK_DST (1); - *dst++ = c; - } - else - { - if ((code = ENCODE_CHAR (charset_roman, c)) != MCHAR_INVALID_CODE) - { - CHECK_DST (1); - *dst++ = c; - } - else if ((code = ENCODE_CHAR (charset_kanji, c)) - != MCHAR_INVALID_CODE) - { - int c1 = code >> 8, c2 = code & 0xFF; - code = JIS_TO_SJIS (c1, c2); - CHECK_DST (2); - *dst++ = code >> 8; - *dst++ = code & 0xFF; - } - else if ((code = ENCODE_CHAR (charset_kana, c)) - != MCHAR_INVALID_CODE) - { - CHECK_DST (1); - *dst++ = code | 0x80; - } - else - { - if (! converter->lenient) - break; - len = encode_unsupporeted_char (c, dst, dst_end, - mt, from + nchars); - if (len == 0) - goto insufficient_destination; - dst += len; - } - } - src += bytes; - nchars++; - } - /* We reach here because of an unsupported char. */ - converter->result = MCONVERSION_RESULT_INVALID_CHAR; - goto finish; - - insufficient_destination: - converter->result = MCONVERSION_RESULT_INSUFFICIENT_DST; - - finish: - converter->nchars += nchars; - converter->nbytes += dst - destination; - return (converter->result == MCONVERSION_RESULT_INVALID_CHAR ? -1 : 0); -} - - -static MCodingSystem * -find_coding (MSymbol name) -{ - MCodingSystem *coding = (MCodingSystem *) msymbol_get (name, Mcoding); - - if (! coding) - { - MPlist *param = mplist_get (coding_definition_list, name); - - if (! param) - return NULL; - param = mplist__from_plist (param); - mconv_define_coding (MSYMBOL_NAME (name), param, NULL, NULL, NULL, NULL); - coding = (MCodingSystem *) msymbol_get (name, Mcoding); - M17N_OBJECT_UNREF (param); - } - return coding; -} - -#define BINDING_NONE 0 -#define BINDING_BUFFER 1 -#define BINDING_STREAM 2 - -#define CONVERT_WORKSIZE 0x10000 - - -/* Internal API */ - -int -mcoding__init (void) -{ - int i; - MPlist *param, *charsets, *pl; - - MLIST_INIT1 (&coding_list, codings, 128); - coding_definition_list = mplist (); - - /* ISO-2022 specific initialize routine. */ - for (i = 0; i < 0x20; i++) - iso_2022_code_class[i] = ISO_control_0; - for (i = 0x21; i < 0x7F; i++) - iso_2022_code_class[i] = ISO_graphic_plane_0; - for (i = 0x80; i < 0xA0; i++) - iso_2022_code_class[i] = ISO_control_1; - for (i = 0xA1; i < 0xFF; i++) - iso_2022_code_class[i] = ISO_graphic_plane_1; - iso_2022_code_class[0x20] = iso_2022_code_class[0x7F] = ISO_0x20_or_0x7F; - iso_2022_code_class[0xA0] = iso_2022_code_class[0xFF] = ISO_0xA0_or_0xFF; - iso_2022_code_class[0x0E] = ISO_shift_out; - iso_2022_code_class[0x0F] = ISO_shift_in; - iso_2022_code_class[0x19] = ISO_single_shift_2_7; - iso_2022_code_class[0x1B] = ISO_escape; - iso_2022_code_class[0x8E] = ISO_single_shift_2; - iso_2022_code_class[0x8F] = ISO_single_shift_3; - iso_2022_code_class[0x9B] = ISO_control_sequence_introducer; - - Mcoding = msymbol ("coding"); - - Mutf = msymbol ("utf"); - Miso_2022 = msymbol ("iso-2022"); - - Mreset_at_eol = msymbol ("reset-at-eol"); - Mreset_at_cntl = msymbol ("reset-at-cntl"); - Meight_bit = msymbol ("eight-bit"); - Mlong_form = msymbol ("long-form"); - Mdesignation_g0 = msymbol ("designation-g0"); - Mdesignation_g1 = msymbol ("designation-g1"); - Mdesignation_ctext = msymbol ("designation-ctext"); - Mdesignation_ctext_ext = msymbol ("designation-ctext-ext"); - Mlocking_shift = msymbol ("locking-shift"); - Msingle_shift = msymbol ("single-shift"); - Msingle_shift_7 = msymbol ("single-shift-7"); - Meuc_tw_shift = msymbol ("euc-tw-shift"); - Miso_6429 = msymbol ("iso-6429"); - Mrevision_number = msymbol ("revision-number"); - Mfull_support = msymbol ("full-support"); - Mmaybe = msymbol ("maybe"); - - Mtype = msymbol ("type"); - Mcharsets = msymbol_as_managing_key ("charsets"); - Mflags = msymbol_as_managing_key ("flags"); - Mdesignation = msymbol_as_managing_key ("designation"); - Minvocation = msymbol_as_managing_key ("invocation"); - Mcode_unit = msymbol ("code-unit"); - Mbom = msymbol ("bom"); - Mlittle_endian = msymbol ("little-endian"); - - param = mplist (); - charsets = mplist (); - pl = param; - /* Setup predefined codings. */ - mplist_set (charsets, Msymbol, Mcharset_ascii); - pl = mplist_add (pl, Mtype, Mcharset); - pl = mplist_add (pl, Mcharsets, charsets); - Mcoding_us_ascii = mconv_define_coding ("us-ascii", param, - NULL, NULL, NULL, NULL); - - { - MSymbol alias = msymbol ("ANSI_X3.4-1968"); - MCodingSystem *coding - = (MCodingSystem *) msymbol_get (Mcoding_us_ascii, Mcoding); - - msymbol_put (alias, Mcoding, coding); - alias = msymbol__canonicalize (alias); - msymbol_put (alias, Mcoding, coding); - } - - mplist_set (charsets, Msymbol, Mcharset_iso_8859_1); - Mcoding_iso_8859_1 = mconv_define_coding ("iso-8859-1", param, - NULL, NULL, NULL, NULL); - - mplist_set (charsets, Msymbol, Mcharset_m17n); - mplist_put (param, Mtype, Mutf); - mplist_put (param, Mcode_unit, (void *) 8); - Mcoding_utf_8_full = mconv_define_coding ("utf-8-full", param, - NULL, NULL, NULL, NULL); - - mplist_set (charsets, Msymbol, Mcharset_unicode); - Mcoding_utf_8 = mconv_define_coding ("utf-8", param, - NULL, NULL, NULL, NULL); - - mplist_put (param, Mcode_unit, (void *) 16); - mplist_put (param, Mbom, Mmaybe); -#ifndef WORDS_BIGENDIAN - mplist_put (param, Mlittle_endian, Mt); -#endif - Mcoding_utf_16 = mconv_define_coding ("utf-16", param, - NULL, NULL, NULL, NULL); - - mplist_put (param, Mcode_unit, (void *) 32); - Mcoding_utf_32 = mconv_define_coding ("utf-32", param, - NULL, NULL, NULL, NULL); - - mplist_put (param, Mcode_unit, (void *) 16); - mplist_put (param, Mbom, Mnil); - mplist_put (param, Mlittle_endian, Mnil); - Mcoding_utf_16be = mconv_define_coding ("utf-16be", param, - NULL, NULL, NULL, NULL); - - mplist_put (param, Mcode_unit, (void *) 32); - Mcoding_utf_32be = mconv_define_coding ("utf-32be", param, - NULL, NULL, NULL, NULL); - - mplist_put (param, Mcode_unit, (void *) 16); - mplist_put (param, Mlittle_endian, Mt); - Mcoding_utf_16le = mconv_define_coding ("utf-16le", param, - NULL, NULL, NULL, NULL); - - mplist_put (param, Mcode_unit, (void *) 32); - Mcoding_utf_32le = mconv_define_coding ("utf-32le", param, - NULL, NULL, NULL, NULL); - - mplist_put (param, Mtype, Mnil); - mplist_set (charsets, Msymbol, Mcharset_ascii); - Mcoding_sjis = mconv_define_coding ("sjis", param, - reset_coding_sjis, - decode_coding_sjis, - encode_coding_sjis, NULL); - - M17N_OBJECT_UNREF (charsets); - M17N_OBJECT_UNREF (param); - - return 0; -} - -void -mcoding__fini (void) -{ - int i; - MPlist *plist; - - for (i = 0; i < coding_list.used; i++) - { - MCodingSystem *coding = coding_list.codings[i]; - - if (coding->extra_info) - free (coding->extra_info); - if (coding->extra_spec) - free (coding->extra_spec); - free (coding); - } - MLIST_FREE1 (&coding_list, codings); - MPLIST_DO (plist, coding_definition_list) - M17N_OBJECT_UNREF (MPLIST_VAL (plist)); - M17N_OBJECT_UNREF (coding_definition_list); -} - -void -mconv__define_coding_from_charset (MSymbol sym) -{ - MPlist *param = mplist (), *charsets = mplist (); - - mplist_set (charsets, Msymbol, sym); - mplist_add (param, Mtype, Mcharset); - mplist_add (param, Mcharsets, charsets); - mconv_define_coding (msymbol_name (sym), param, NULL, NULL, NULL, NULL); - M17N_OBJECT_UNREF (charsets); - M17N_OBJECT_UNREF (param); -} - -void -mconv__register_charset_coding (MSymbol sym) -{ - if (! mplist_find_by_key (coding_definition_list, sym)) - { - MPlist *param = mplist (), *charsets = mplist (); - - mplist_set (charsets, Msymbol, sym); - mplist_add (param, Msymbol, Mtype); - mplist_add (param, Msymbol, Mcharset); - mplist_add (param, Msymbol, Mcharsets); - mplist_add (param, Mplist, charsets); - mplist_put (coding_definition_list, sym, param); - M17N_OBJECT_UNREF (charsets); - } -} - - -int -mcoding__load_from_database () -{ - MDatabase *mdb = mdatabase_find (msymbol ("coding-list"), Mnil, Mnil, Mnil); - MPlist *def_list, *plist; - MPlist *definitions = coding_definition_list; - int mdebug_mask = MDEBUG_CODING; - - if (! mdb) - return 0; - MDEBUG_PUSH_TIME (); - def_list = (MPlist *) mdatabase_load (mdb); - MDEBUG_PRINT_TIME ("CODING", (stderr, " to load the data.")); - MDEBUG_POP_TIME (); - if (! def_list) - return -1; - - MDEBUG_PUSH_TIME (); - MPLIST_DO (plist, def_list) - { - MPlist *pl; - MSymbol name; - - if (! MPLIST_PLIST_P (plist)) - MERROR (MERROR_CHARSET, -1); - pl = MPLIST_PLIST (plist); - if (! MPLIST_SYMBOL_P (pl)) - MERROR (MERROR_CHARSET, -1); - name = MPLIST_SYMBOL (pl); - pl = MPLIST_NEXT (pl); - definitions = mplist_add (definitions, name, pl); - M17N_OBJECT_REF (pl); - } - - M17N_OBJECT_UNREF (def_list); - MDEBUG_PRINT_TIME ("CODING", (stderr, " to parse the loaded data.")); - MDEBUG_POP_TIME (); - return 0; -} - -/*** @} */ -#endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */ - -/* External API */ - -/*** @addtogroup m17nConv */ -/*** @{ */ -/*=*/ - -/***en @name Variables: Symbols representing a coding system */ -/***ja @name ÊÑ¿ô: ÄêµÁºÑ¤ß¥³¡¼¥É·Ï¤ò»ØÄꤹ¤ë¤¿¤á¤Î¥·¥ó¥Ü¥ë */ -/*** @{ */ -/*=*/ - -/***en - @brief Symbol for the coding system US-ASCII - - The symbol #Mcoding_us_ascii has name "us-ascii" and - represents a coding system for the CES US-ASCII. */ - -/***ja - @brief MIME charset "US-ASCII" ¤ËÂбþ¤¹¤ë¥³¡¼¥É·Ï¤Î¥·¥ó¥Ü¥ë - - ¥·¥ó¥Ü¥ë @c Mcoding_us_ascii ¤Ï "us-ascii" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢ - MIME charset "US-ASCII" ¤ËÂбþ¤¹¤ë¥³¡¼¥É·Ï¤ò»ØÄꤹ¤ë¤¿¤á - ¤Ë»È¤ï¤ì¤ë¡£ - */ -MSymbol Mcoding_us_ascii; -/*=*/ - -/***en - @brief Symbol for the coding system ISO-8859-1 - - The symbol #Mcoding_iso_8859_1 has name "iso-8859-1" and - represents a coding system for the CES ISO-8859-1. */ - -/***ja - @brief MIME charset "ISO-8859-1" ¤ËÂбþ¤¹¤ë¥³¡¼¥É·Ï¤Î¥·¥ó¥Ü¥ë - - ¥·¥ó¥Ü¥ë @c Mcoding_iso_8859_1 ¤Ï "iso-8859-1" ¤È¤¤¤¦Ì¾Á° - ¤ò»ý¤Á¡¢MIME charset "ISO-8859-1" ¤ËÂбþ¤¹¤ë¥³¡¼¥É·Ï¤ò»Ø - Äꤹ¤ë¤¿¤á¤Ë»È¤ï¤ì¤ë¡£ */ - -MSymbol Mcoding_iso_8859_1; -/*=*/ - -/***en - @brief Symbol for the coding system UTF-8 - - The symbol #Mcoding_utf_8 has name "utf-8" and represents - a coding system for the CES UTF-8. */ - -/***ja - @brief RFC 2279 ¤Î "UTF-8" ¤ËÂбþ¤¹¤ë¥³¡¼¥É·Ï¤Î¥·¥ó¥Ü¥ë¡ÊUnicode ÍÑ¡Ë - - ¥·¥ó¥Ü¥ë @c Mcoding_utf_8 ¤Ï "utf-8" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢ - RFC 2279 ¤ÇÄêµÁ¤µ¤ì¤ë"UTF-8" ¤ËÂбþ¤¹¤ë¥³¡¼¥É·Ï¤ò»ØÄꤹ¤ë - ¤¿¤á¤Ë»È¤ï¤ì¤ë¡£¤³¤Î¥³¡¼¥É·Ï¤Ï Unicode ¤ÎÁ´¤Æ¤Îʸ»ú¤ò¥µ¥Ý¡¼¥È¤¹¤ë¡£ - */ - -MSymbol Mcoding_utf_8; -/*=*/ - -/***en - @brief UTF-8-FULL - - - The symbol #Mcoding_utf_8_full has name "utf-8-full" and - represents a coding system that is a extension of UTF-8. This - coding system uses the same encoding algorithm as UTF-8 but is not - limited to the Unicode characters. It can encode all characters - supported by the m17n library. */ - -/***ja - @brief RFC 2279 ¤Î "UTF-8" ¤ËÂбþ¤¹¤ë¥³¡¼¥É·Ï¤Î¥·¥ó¥Ü¥ë¡ÊÁ´Ê¸»úÍÑ¡Ë - - ¥·¥ó¥Ü¥ë @c Mcoding_utf_8_full ¤Ï "utf-8-full" ¤È¤¤¤¦Ì¾Á° - ¤ò»ý¤Á¡¢RFC 2279 ¤ÇÄêµÁ¤µ¤ì¤ë"UTF-8" ¤ËÂбþ¤¹¤ë¥³¡¼¥É·Ï¤ò - »ØÄꤹ¤ë¤¿¤á¤Ë»È¤ï¤ì¤ë¡£¤³¤Î¥³¡¼¥É·Ï¤Ï m17n ¥é¥¤¥Ö¥é¥ê¤¬°·¤¦Á´¤Æ¤Î - ʸ»ú¤ò¥µ¥Ý¡¼¥È¤¹¤ë¡£ */ - -MSymbol Mcoding_utf_8_full; -/*=*/ - -/***en - @brief UTF-16 - - The symbol #Mcoding_utf_16 has name "utf-16" and - represents a coding system for the CES UTF-16 (RFC 2279). */ -/***ja - @brief RFC 2781 ¤Î "UTF-16" ¤ËÂбþ¤¹¤ë¥³¡¼¥É·Ï¤Î¥·¥ó¥Ü¥ë - - ¥·¥ó¥Ü¥ë @c Mcoding_utf_16 ¤Ï "utf-16" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢ - RFC 2279 ¤ÇÄêµÁ¤µ¤ì¤ë"UTF-16" ¤ËÂбþ¤¹¤ë¥³¡¼¥É·Ï¤ò»ØÄꤹ - ¤ë¤¿¤á¤Ë»È¤ï¤ì¤ë¡£¤³¤Î¥³¡¼¥É·Ï¤Ï Unicode ¤ÎÁ´¤Æ¤Îʸ»ú¤ò¥µ¥Ý¡¼¥È¤¹ - ¤ë¡£ */ - -MSymbol Mcoding_utf_16; -/*=*/ - -/***en - @brief UTF-16BE - - The symbol #Mcoding_utf_16be has name "utf-16be" and - represents a coding system for the CES UTF-16BE (RFC 2279). */ - -MSymbol Mcoding_utf_16be; -/*=*/ - -/***en - @brief UTF-16LE - - The symbol #Mcoding_utf_16le has name "utf-16le" and - represents a coding system for the CES UTF-16LE (RFC 2279). */ - -MSymbol Mcoding_utf_16le; -/*=*/ - -/***en - @brief UTF-32 - - The symbol #Mcoding_utf_32 has name "utf-32" and - represents a coding system for the CES UTF-32 (RFC 2279). */ - -MSymbol Mcoding_utf_32; -/*=*/ - -/***en - @brief UTF-32be - - The symbol #Mcoding_utf_32be has name "utf-32be" and - represents a coding system for the CES UTF-32BE (RFC 2279). */ - -MSymbol Mcoding_utf_32be; -/*=*/ - -/***en - @brief UTF-32LE - - The symbol #Mcoding_utf_32le has name "utf-32le" and - represents a coding system for the CES UTF-32LE (RFC 2279). */ -MSymbol Mcoding_utf_32le; -/*=*/ - -/***en - @brief SJIS - - The symbol #Mcoding_sjis has name "sjis" and represents a coding - system for the CES Shift-JIS. */ - -MSymbol Mcoding_sjis; -/*** @} */ -/*=*/ - -/***en - @name Variables: Parameter keys for mconv_define_coding (). */ -/*** @{ */ -/*=*/ - -/***en - Parameter key for mconv_define_coding () (which see). */ -MSymbol Mtype; -/*=*/ - -MSymbol Mcharsets; -MSymbol Mflags; -MSymbol Mdesignation; -MSymbol Minvocation; -MSymbol Mcode_unit; -MSymbol Mbom; -MSymbol Mlittle_endian; -/*** @} */ -/*=*/ - -/***en - @name Variables: Symbols representing coding system type. */ -/*** @{ */ -/*=*/ - -/***en - Symbol that can be a value of the #Mtype parameter of a coding - system used in an argument to the mconv_define_coding () function - (which see). */ - -MSymbol Mutf; -/*=*/ -MSymbol Miso_2022; -/*=*/ -/*** @} */ -/*=*/ - -/***en - @name Variables: Symbols appearing in the value of #Mfrag parameter. */ -/*** @{ */ -/*=*/ - -/***en - Symbol that can be a value of the #Mflags parameter of a coding - system used in an argument to the mconv_define_coding () function - (which see). */ -MSymbol Mreset_at_eol; -/*=*/ -MSymbol Mreset_at_cntl; -MSymbol Meight_bit; -MSymbol Mlong_form; -MSymbol Mdesignation_g0; -MSymbol Mdesignation_g1; -MSymbol Mdesignation_ctext; -MSymbol Mdesignation_ctext_ext; -MSymbol Mlocking_shift; -MSymbol Msingle_shift; -MSymbol Msingle_shift_7; -MSymbol Meuc_tw_shift; -MSymbol Miso_6429; -MSymbol Mrevision_number; -MSymbol Mfull_support; -/*** @} */ -/*=*/ - -/***en - @name Variables: etc - - Remaining variables. */ -/***ja @name ÊÑ¿ô: ¤½¤Î¾ */ -/*** @{ */ -/*=*/ -/***en - @brief Symbol whose name is "maybe". - - The variable #Mmaybe is a symbol of name "maybe". It is - used a value of #Mbom parameter of the function - mconv_define_coding () (which see). */ - -MSymbol Mmaybe; -/*=*/ - -/***en - @brief The symbol @c Mcoding - - Any decoded M-text has a text property whose key is the predefined - symbol @c Mcoding. The name of @c Mcoding is - "coding". */ - -/***ja - @brief ¥·¥ó¥Ü¥ë @c Mcoding - - ¥Ç¥³¡¼¥É¤µ¤ì¤¿ M-text ¤Ï¡¢¥­¡¼¤¬ @c Mcoding ¤Ç¤¢¤ë¤è¤¦¤Ê¥Æ¥­¥¹¥È¥× - ¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¡£¥·¥ó¥Ü¥ë @c Mcoding ¤Ï "coding" ¤È¤¤¤¦Ì¾ - Á°¤Ç¤¢¤é¤«¤¸¤áÄêµÁ¤µ¤ì¤Æ¤¤¤ë¡£ */ - -MSymbol Mcoding; -/*=*/ -/*** @} */ -/*=*/ - -/***en - @brief Define a coding system - - The mconv_define_coding () function defines a new coding system - and makes it accessive via a symbol whose name is $NAME. $PLIST - specifies parameters of the charset as below: - -
    - -
  • Key is @c Mtype, value is a symbol - - The value specifies the type of the coding system. It must be - #Mcharset, #Mutf, #Miso_2022, or #Mnil. - - If the type is #Mcharset, $EXTRA_INFO is ignored. - - If the type is #Miso_2022, $EXTRA_INFO must be a pointer to - #MCodingInfoISO2022. - - If the type is #Mutf, $EXTRA_INFO must be a pointer to - #MCodingInfoUTF. - - If the type is #Mnil, the argument $RESETTER, $DECODER, and - $ENCODER must be supplied. $EXTRA_INFO is ignored. Otherwise, - they can be @c NULL and the m17n library provides proper defaults. - -
  • Key is #Mcharsets, value is a plist - - The value specifies a list charsets supported by the coding - system. The keys of the plist must be #Msymbol, and the values - must be symbols representing charsets. - -
  • Key is #Mflags, value is a plist - - If the type is #Miso_2022, the values specifies flags to control - the ISO 2022 interpreter. The keys of the plist must e @c - Msymbol, and values must be one of the following. - -
      - -
    • #Mreset_at_eol - - If this flag exits, designation and invocation status is reset to - the initial state at the end of line. - -
    • #Mreset_at_cntl - - If this flag exists, designation and invocation status is reset to - the initial state at a control character. - -
    • #Meight_bit - - If this flag exists, the graphic plane right is used. - -
    • #Mlong_form - - If this flag exists, the over-long escape sequences (ESC '$' '(' - ) are used for designating the charsets JISX0208.1978, - GB2312, and JISX0208. - -
    • #Mdesignation_g0 - - If this flag and #Mfull_support exists, designates charsets not - listed in the charset list to the graphic register G0. - -
    • #Mdesignation_g1 - - If this flag and #Mfull_support exists, designates charsets not - listed in the charset list to the graphic register G1. - -
    • #Mdesignation_ctext - - If this flag and #Mfull_support exists, designates charsets not - listed in the charset list to a graphic register G0 or G1 based on - the criteria of the Compound Text. - -
    • #Mdesignation_ctext_ext - - If this flag and #Mfull_support exists, designates charsets not - listed in the charset list to a graphic register G0 or G1, or use - extended segment for such charsets based on the criteria of the - Compound Text. - -
    • #Mlocking_shift - - If this flag exists, use locking shift. - -
    • #Msingle_shift - - If this flag exists, use single shift. - -
    • #Msingle_shift_7 - - If this flag exists, use 7-bit single shift code (0x19). - -
    • #Meuc_tw_shift; - - If this flag exists, use a special shifting according to EUC-TW. - -
    • #Miso_6429 - - This flag is currently ignored. - -
    • #Mrevision_number - - If this flag exists, use a revision number escape sequence to - designate a charset that has a revision number. - -
    • #Mfull_support - - If this flag exists, support all charsets registered in the - International Registry. - -
    - -
  • Key is #Mdesignation, value is a plist - - If the type is #Miso_2022, the value specifies how to designate - each supported characters. The keys of the plist must be @c - Minteger, and the values must be numbers indicating a graphic - registers. The Nth element value is for the Nth charset of the - charset list. The value 0..3 means that it is assumed that a - charset is already designated to the graphic register 0..3. The - negative value G (-4..-1) means that a charset is not designated - to any register at first, and if necessary, is designated to the - (G+4) graphic register. - -
  • Key is #Minvocation, value is a plist - - If the type is #Miso_2022, the value specifies how to invocate - each graphic registers. The plist length must be one or two. The - keys of the plist must be #Minteger, and the values must be - numbers indicating a graphic register. The value of the first - element specifies which graphic register is invocated to the - graphic plane left. If the length is one, no graphic register is - invocated to the graphic plane right. Otherwise, the value of the - second element specifies which graphic register is invocated to - the graphic plane right. - -
  • Key is #Mcode_unit, value is an integer - - If the type is #Mutf, the value specifies the bit length of a - code-unit. It must be 8, 16, or 32. - -
  • Key is #Mbom, value is a symbol - - If the type is #Mutf and the code-unit bit length is 16 or 32, - it specifies whether or not to use BOM (Byte Order Mark). If the - value is #Mnil (default), BOM is not used, else if the value is - #Mmaybe, the existence of BOM is detected at decoding time, else - BOM is used. - -
  • Key is #Mlittle_endian, value is a symbol - - If the type is #Mutf and the code-unit bit length is 16 or 32, - it specifies whether or not the encoding is little endian. If the - value is #Mnil (default), it is big endian, else it is little - endian. - -
- - $RESETTER is a pointer to a function that resets a converter for - the coding system to the initial status. The pointed function is - called with one argument, a pointer to a converter object. - - $DECODER is a pointer to a function that decodes a byte sequence - according to the coding system. The pointed function is called - with four arguments: - - @li A pointer to the byte sequence to decode. - @li The number of bytes to decode. - @li A pointer to an M-text to which the decoded characters are appended. - @li A pointer to a converter object. - - $DECODER must return 0 if it succeeds. Otherwise it must return -1. - - $ENCODER is a pointer to a function that encodes an M-text - according to the coding system. The pointed function is called - with six arguments: - - @li A pointer to the M-text to encode. - @li The starting position of the encoding. - @li The ending position of the encoding. - @li A pointer to a memory area where the produced bytes are stored. - @li The size of the memory area. - @li A pointer to a converter object. - - $ENCODER must return 0 if it succeeds. Otherwise it must return -1. - - $EXTRA_INFO is a pointer to a data structure that contains extra - information about the coding system. The type of the data - structure depends on $TYPE. - - @return - - If the operation was successful, mconv_define_coding () returns a - symbol whose name is $NAME. If an error is detected, it returns - #Mnil and assigns an error code to the external variable @c - merror_code. */ - -/***ja - @brief ¥³¡¼¥É·Ï¤ÎÄêµÁ - - ´Ø¿ô mconv_define_coding () ¤Ï¡¢¿·¤·¤¤¥³¡¼¥É·Ï¤òÄêµÁ¤·¡¢¤½¤ì¤ò - $NAME ¤È¤¤¤¦Ì¾Á°¤Î¥·¥ó¥Ü¥ë·Ðͳ¤Ç¥¢¥¯¥»¥¹¤Ç¤­¤ë¤è¤¦¤Ë¤¹¤ë¡£ - - $TYPE ¤Ï Îóµó·¿ #MCodingType ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ê¡¢¥³¡¼¥É·Ï¤Î¹½Â¤¤ò - »ØÄꤹ¤ë¡£ - - $CHARSET_NAMES ¤Ï¥µ¥Ý¡¼¥È¤¹¤ëʸ»ú¥»¥Ã¥È¤òɽ¤ï¤¹¥·¥ó¥Ü¥ë¤ÎÇÛÎó¤Ç¤¢¤ê¡¢ - $NCHARSETS ¤Ï¤½¤ÎÍ×ÁÇ¿ô¤Ç¤¢¤ë¡£ - - $TYPE ¤¬ #MCODING_TYPE_MISC ¤Ç¤¢¤ë¾ì¹ç¤Ë¤Ï¡¢$RESETTER, $DECODER, - $ENCODER ¤òÍ¿¤¨¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤½¤ì°Ê³°¤Î¾ì¹ç¤Ë¤Ï¤³¤ì¤é¤Ï @c - NULL ¤Ç¹½¤ï¤Ê¤¤¡£¤½¤ÎºÝ¤Ë¤Ï m17n ¥é¥¤¥Ö¥é¥ê¤¬Å¬Àڤʥǥե©¥ë¥ÈÃͤò - Í¿¤¨¤ë¡£ - - $RESETTER ¤Ï¤³¤Î¥³¡¼¥É·ÏÍѤΥ³¥ó¥Ð¡¼¥¿¤ò½é´ü¾õÂ֤˥ꥻ¥Ã¥È¤¹¤ë´Ø¿ô - ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¤³¤Î´Ø¿ô¤Ï¥³¥ó¥Ð¡¼¥¿¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤È - ¤¤¤¦£±°ú¿ô¤ò¤È¤ë¡£ - - $DECODER ¤Ï¥Ð¥¤¥ÈÎó¤ò¤³¤Î¥³¡¼¥É·Ï¤Ë½¾¤Ã¤Æ¥Ç¥³¡¼¥É¤¹¤ë´Ø¿ô¤Ø¤Î¥Ý¥¤ - ¥ó¥¿¤Ç¤¢¤ë¡£¤³¤Î´Ø¿ô¤Ï°Ê²¼¤Î4°ú¿ô¤ò¤È¤ë¡£ - - @li ¥Ð¥¤¥ÈÎó¤Ø¤Î¥Ý¥¤¥ó¥¿ - @li ¥Ç¥³¡¼¥É¤¹¤Ù¤­¥Ð¥¤¥È¿ô - @li ¥Ç¥³¡¼¥É·ë²Ì¤Îʸ»ú¤òÉղ乤ë M-text ¤Ø¤Î¥Ý¥¤¥ó¥¿ - @li ¥³¥ó¥Ð¡¼¥¿¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿ - - $DECODER ¤ÏÀ®¸ù¤·¤¿¤È¤­¤Ë¤Ï0¤ò¡¢¼ºÇÔ¤·¤¿¤È¤­¤Ë¤Ï-1¤òÊÖ¤µ¤Ê¤¯¤Æ¤Ï¤Ê - ¤é¤Ê¤¤¡£ - - $ENCODER ¤Ï M-text ¤ò¤³¤Î¥³¡¼¥É·Ï¤Ë½¾¤Ã¤Æ¥¨¥ó¥³¡¼¥É¤¹ - ¤ë´Ø¿ô¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¤³¤Î´Ø¿ô¤Ï°Ê²¼¤Î6°ú¿ô¤ò¤È¤ë¡£ - - @li M-text ¤Ø¤Î¥Ý¥¤¥ó¥¿ - @li M-text ¤Î¥¨¥ó¥³¡¼¥É³«»Ï°ÌÃÖ - @li M-text ¤Î¥¨¥ó¥³¡¼¥É½ªÎ»°ÌÃÖ - @li À¸À®¤·¤¿¥Ð¥¤¥È¤òÊÝ»ý¤¹¤ë¥á¥â¥êÎΰè¤Ø¤Î¥Ý¥¤¥ó¥¿ - @li ¥á¥â¥êÎΰè¤Î¥µ¥¤¥º - @li ¥³¥ó¥Ð¡¼¥¿¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿ - - $ENCODER ¤ÏÀ®¸ù¤·¤¿¤È¤­¤Ë¤Ï0¤ò¡¢¼ºÇÔ¤·¤¿¤È¤­¤Ë¤Ï-1¤òÊÖ¤µ¤Ê¤¯¤Æ¤Ï¤Ê - ¤é¤Ê¤¤¡£ - - $EXTRA_INFO ¤Ï¥³¡¼¥Ç¥£¥°¥·¥¹¥Æ¥à¤Ë´Ø¤¹¤ëÄɲþðÊó¤ò´Þ¤à¥Ç¡¼¥¿¹½Â¤¤Ø - ¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¤³¤Î¥Ç¡¼¥¿¹½Â¤¤Î¥¿¥¤¥×¤Ï $TYPE ¤Ë°Í¸¤¹¤ë¡£ - - $TYPE ¤¬ #MCODING_TYPE_ISO_2022 ¤Ç¤¢¤ì¤Ð¡¢$EXTRA_INFO ¤Ï @c - MCodingInfoISO2022 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ - - $TYPE ¤¬ #MCODING_TYPE_UTF ¤Ç¤¢¤ì¤Ð¡¢$EXTRA_INFO ¤Ï @c - MCodingInfoUTF ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ - - $TYPE ¤¬ #MCODING_TYPE_CHARSET, #MCODING_TYPE_MISC ¤Î¤É¤ì¤«¤Ç - ¤¢¤ì¤Ð¡¢$EXTRA_INFO ¤Ï̵»ë¤µ¤ì¤ë¡£ - - @return - - ½èÍý¤ËÀ®¸ù¤¹¤ì¤Ð mconv_define_coding () ¤Ï $NAME ¤È¤¤¤¦Ì¾Á°¤Î¥· - ¥ó¥Ü¥ë¤òÊÖ¤¹¡£¤³¤Î¥·¥ó¥Ü¥ë¤Ï¡¢¥­¡¼¤¬ $Mcoding ¤Ç¡¢ºî¤é¤ì¤¿¥³¡¼¥É·Ï - ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÃͤȤ¹¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¡£ ¥¨¥é¡¼¤¬¸¡½Ð¤µ¤ì - ¤¿¾ì¹ç¤Ï Mnil ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ - */ - -/*** - @errors - @c MERROR_CODING */ - -MSymbol -mconv_define_coding (char *name, MPlist *plist, - int (*resetter) (MConverter *), - int (*decoder) (unsigned char *, int, MText *, - MConverter *), - int (*encoder) (MText *, int, int, - unsigned char *, int, - MConverter *), - void *extra_info) -{ - MSymbol sym = msymbol (name); - int i; - MCodingSystem *coding; - MPlist *pl; - - MSTRUCT_MALLOC (coding, MERROR_CODING); - coding->name = sym; - if ((coding->type = (MSymbol) mplist_get (plist, Mtype)) == Mnil) - coding->type = Mcharset; - pl = (MPlist *) mplist_get (plist, Mcharsets); - if (! pl) - MERROR (MERROR_CODING, Mnil); - coding->ncharsets = mplist_length (pl); - if (coding->ncharsets > NUM_SUPPORTED_CHARSETS) - coding->ncharsets = NUM_SUPPORTED_CHARSETS; - for (i = 0; i < coding->ncharsets; i++, pl = MPLIST_NEXT (pl)) - { - MSymbol charset_name; - - if (MPLIST_KEY (pl) != Msymbol) - MERROR (MERROR_CODING, Mnil); - charset_name = MPLIST_SYMBOL (pl); - if (! (coding->charsets[i] = MCHARSET (charset_name))) - MERROR (MERROR_CODING, Mnil); - } - - coding->resetter = resetter; - coding->decoder = decoder; - coding->encoder = encoder; - coding->ascii_compatible = 0; - coding->extra_info = extra_info; - coding->extra_spec = NULL; - coding->ready = 0; - - if (coding->type == Mcharset) - { - if (! coding->resetter) - coding->resetter = reset_coding_charset; - if (! coding->decoder) - coding->decoder = decode_coding_charset; - if (! coding->encoder) - coding->encoder = encode_coding_charset; - } - else if (coding->type == Mutf) - { - MCodingInfoUTF *info = malloc (sizeof (MCodingInfoUTF)); - MSymbol val; - - if (! coding->resetter) - coding->resetter = reset_coding_utf; - - info->code_unit_bits = (int) mplist_get (plist, Mcode_unit); - if (info->code_unit_bits == 8) - { - if (! coding->decoder) - coding->decoder = decode_coding_utf_8; - if (! coding->encoder) - coding->encoder = encode_coding_utf_8; - } - else if (info->code_unit_bits == 16) - { - if (! coding->decoder) - coding->decoder = decode_coding_utf_16; - if (! coding->encoder) - coding->encoder = encode_coding_utf_16; - } - else if (info->code_unit_bits == 32) - { - if (! coding->decoder) - coding->decoder = decode_coding_utf_32; - if (! coding->encoder) - coding->encoder = encode_coding_utf_32; - } - else - MERROR (MERROR_CODING, Mnil); - val = (MSymbol) mplist_get (plist, Mbom); - if (val == Mnil) - info->bom = 1; - else if (val == Mmaybe) - info->bom = 0; - else - info->bom = 2; - - info->endian = (mplist_get (plist, Mlittle_endian) ? 1 : 0); - coding->extra_info = info; - } - else if (coding->type == Miso_2022) - { - MCodingInfoISO2022 *info = malloc (sizeof (MCodingInfoISO2022)); - - if (! coding->resetter) - coding->resetter = reset_coding_iso_2022; - if (! coding->decoder) - coding->decoder = decode_coding_iso_2022; - if (! coding->encoder) - coding->encoder = encode_coding_iso_2022; - - info->initial_invocation[0] = 0; - info->initial_invocation[1] = -1; - pl = (MPlist *) mplist_get (plist, Minvocation); - if (pl) - { - if (MPLIST_KEY (pl) != Minteger) - MERROR (MERROR_CODING, Mnil); - info->initial_invocation[0] = MPLIST_INTEGER (pl); - if (! MPLIST_TAIL_P (pl)) - { - pl = MPLIST_NEXT (pl); - if (MPLIST_KEY (pl) != Minteger) - MERROR (MERROR_CODING, Mnil); - info->initial_invocation[1] = MPLIST_INTEGER (pl); - } - } - memset (info->designations, 0, sizeof (info->designations)); - for (i = 0, pl = (MPlist *) mplist_get (plist, Mdesignation); - i < 32 && pl && MPLIST_KEY (pl) == Minteger; - i++, pl = MPLIST_NEXT (pl)) - info->designations[i] = MPLIST_INTEGER (pl); - - info->flags = 0; - MPLIST_DO (pl, (MPlist *) mplist_get (plist, Mflags)) - { - MSymbol val; - - if (MPLIST_KEY (pl) != Msymbol) - MERROR (MERROR_CODING, Mnil); - val = MPLIST_SYMBOL (pl); - if (val == Mreset_at_eol) - info->flags |= MCODING_ISO_RESET_AT_EOL; - else if (val == Mreset_at_cntl) - info->flags |= MCODING_ISO_RESET_AT_CNTL; - else if (val == Meight_bit) - info->flags |= MCODING_ISO_EIGHT_BIT; - else if (val == Mlong_form) - info->flags |= MCODING_ISO_LOCKING_SHIFT; - else if (val == Mdesignation_g0) - info->flags |= MCODING_ISO_DESIGNATION_G0; - else if (val == Mdesignation_g1) - info->flags |= MCODING_ISO_DESIGNATION_G1; - else if (val == Mdesignation_ctext) - info->flags |= MCODING_ISO_DESIGNATION_CTEXT; - else if (val == Mdesignation_ctext_ext) - info->flags |= MCODING_ISO_DESIGNATION_CTEXT_EXT; - else if (val == Mlocking_shift) - info->flags |= MCODING_ISO_LOCKING_SHIFT; - else if (val == Msingle_shift) - info->flags |= MCODING_ISO_SINGLE_SHIFT; - else if (val == Msingle_shift_7) - info->flags |= MCODING_ISO_SINGLE_SHIFT_7; - else if (val == Meuc_tw_shift) - info->flags |= MCODING_ISO_EUC_TW_SHIFT; - else if (val == Miso_6429) - info->flags |= MCODING_ISO_ISO6429; - else if (val == Mrevision_number) - info->flags |= MCODING_ISO_REVISION_NUMBER; - else if (val == Mfull_support) - info->flags |= MCODING_ISO_FULL_SUPPORT; - } - - coding->extra_info = info; - } - else - { - if (! coding->decoder || ! coding->encoder) - MERROR (MERROR_CODING, Mnil); - if (! coding->resetter) - coding->ready = 1; - } - - msymbol_put (sym, Mcoding, coding); - msymbol_put (msymbol__canonicalize (sym), Mcoding, coding); - plist = (MPlist *) mplist_get (plist, Maliases); - if (plist) - { - MPLIST_DO (pl, plist) - { - MSymbol alias; - - if (MPLIST_KEY (pl) != Msymbol) - continue; - alias = MPLIST_SYMBOL (pl); - msymbol_put (alias, Mcoding, coding); - msymbol_put (msymbol__canonicalize (alias), Mcoding, coding); - } - } - - MLIST_APPEND1 (&coding_list, codings, coding, MERROR_CODING); - - return sym; -} - -/*=*/ - -/***en - @brief Resolve coding system name. - - The mconv_resolve_coding () function returns $SYMBOL if it - represents a coding system. Otherwise, canonicalize $SYMBOL as to - a coding system name, and if the canonicalized name represents a - coding system, return it. Otherwise, return Mnil. */ - - -MSymbol -mconv_resolve_coding (MSymbol symbol) -{ - MCodingSystem *coding = find_coding (symbol); - - if (! coding) - { - symbol = msymbol__canonicalize (symbol); - coding = find_coding (symbol); - } - return (coding ? coding->name : Mnil); -} - -/*=*/ - - -/***en - @brief List symbols representing a coding system. - - The mconv_list_codings () function makes an array of symbols - representing a coding system, stores the pointer to the array in a - place pointed to by $SYMBOLS, and returns the length of the array. */ - -int -mconv_list_codings (MSymbol **symbols) -{ - int i = coding_list.used + mplist_length (coding_definition_list); - int j; - MPlist *plist; - - MTABLE_MALLOC ((*symbols), i, MERROR_CODING); - i = 0; - MPLIST_DO (plist, coding_definition_list) - (*symbols)[i++] = MPLIST_KEY (plist); - for (j = 0; j < coding_list.used; j++) - if (! mplist_find_by_key (coding_definition_list, - coding_list.codings[j]->name)) - (*symbols)[i++] = coding_list.codings[j]->name; - return i; -} - -/*=*/ - -/***en - @brief Create a code converter bound to a buffer. - - The mconv_buffer_converter () function creates a pointer to a code - converter for coding system $CODING. The code converter is bound - to buffer area of $N bytes pointed to by $BUF. Subsequent - decodings and encodings are done to/from this buffer area. - - $CODING can be #Mnil. In this case, a coding system associated - with the current locale (LC_CTYPE) is used. - - @return - If the operation was successful, mconv_buffer_converter () returns - the created code converter. Otherwise it returns @c NULL and - assigns an error code to the external variable #merror_code. */ - -/***ja - @brief ¥Ð¥Ã¥Õ¥¡¤Ë·ë¤ÓÉÕ¤±¤é¤ì¤¿¥³¡¼¥É¥³¥ó¥Ð¡¼¥¿¤òºî¤ë - - ´Ø¿ô mconv_buffer_converter () ¤Ï¡¢¥³¡¼¥É·Ï $CODING ÍѤΥ³¡¼¥É¥³¥ó - ¥Ð¡¼¥¿¤òºî¤ë¡£¤³¤Î¥³¡¼¥É¥³¥ó¥Ð¡¼¥¿¤Ï¡¢$BUF ¤Ç¼¨¤µ¤ì¤ëÂ礭¤µ $N ¥Ð - ¥¤¥È¤Î¥Ð¥Ã¥Õ¥¡Îΰè¤Ë·ë¤ÓÉÕ¤±¤é¤ì¤ë¡£¤³¤ì°Ê¹ß¤Î¥Ç¥³¡¼¥É¤ª¤è¤Ó - ¥¨¥ó¥³¡¼¥É¤Ï¡¢¤³¤Î¥Ð¥Ã¥Õ¥¡Îΰè¤ËÂФ·¤Æ¹Ô¤Ê¤ï¤ì¤ë¡£ - - $CODING ¤Ï #Mnil ¤Ç¤¢¤Ã¤Æ¤â¤è¤¤¡£¤³¤Î¾ì¹ç¤Ï¸½ºß¤Î¥í¥±¡¼¥ë - (LC_CTYPE) ¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤¿¥³¡¼¥É·Ï¤¬»È¤ï¤ì¤ë¡£ - - @return - ¤â¤·½èÍý¤¬À®¸ù¤¹¤ì¤Ð mconv_buffer_converter () ¤Ï ºî¤é¤ì¤¿¥³¡¼¥É¥³ - ¥ó¥Ð¡¼¥¿¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code - ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ - - @latexonly \IPAlabel{mconverter} @endlatexonly */ - -/*** - @errors - @c MERROR_SYMBOL, @c MERROR_CODING - - @seealso - mconv_stream_converter () */ - -MConverter * -mconv_buffer_converter (MSymbol name, unsigned char *buf, int n) -{ - MCodingSystem *coding; - MConverter *converter; - MConverterStatus *internal; - - if (name == Mnil) - name = mlocale_get_prop (mlocale__ctype, Mcoding); - coding = find_coding (name); - if (! coding) - MERROR (MERROR_CODING, NULL); - MSTRUCT_CALLOC (converter, MERROR_CODING); - MSTRUCT_CALLOC (internal, MERROR_CODING); - converter->internal_info = internal; - internal->coding = coding; - if (coding->resetter - && (*coding->resetter) (converter) < 0) - { - free (internal); - free (converter); - MERROR (MERROR_CODING, NULL); - } - - internal->unread = mtext (); - internal->work_mt = mtext (); - mtext__enlarge (internal->work_mt, MAX_UTF8_CHAR_BYTES); - internal->buf = buf; - internal->used = 0; - internal->bufsize = n; - internal->binding = BINDING_BUFFER; - - return converter; -} - -/*=*/ - -/***en - @brief Create a code converter bound to a stream. - - The mconv_stream_converter () function create a pointer to a code - converter for coding system $CODING. The code converter is bound - to stream $FP. Subsequent decodings and encodings are done - to/from this stream. - - $CODING can be #Mnil. In this case, a coding system associated - with the current locale (LC_CTYPE) is used. - - @return If the operation was successful, mconv_stream_converter () - returns the created code converter. Otherwise it returns @c NULL - and assigns an error code to the external variable @c - merror_code. */ - -/***ja - @brief ¥¹¥È¥ê¡¼¥à¤Ë·ë¤ÓÉÕ¤±¤é¤ì¤¿¥³¡¼¥É¥³¥ó¥Ð¡¼¥¿¤òºî¤ë - - ´Ø¿ô mconv_stream_converter () ¤Ï¡¢¥³¡¼¥É·Ï $CODING ÍѤΥ³¡¼¥É¥³¥ó - ¥Ð¡¼¥¿¤òºî¤ë¡£¤³¤Î¥³¡¼¥É¥³¥ó¥Ð¡¼¥¿¤Ï¡¢¥¹¥È¥ê¡¼¥à $FP ¤Ë·ë¤ÓÉÕ¤±¤é - ¤ì¤ë¡£¤³¤ì°Ê¹ß¤Î¥Ç¥³¡¼¥É¤ª¤è¤Ó¥¨¥ó¥³¡¼¥É¤Ï¡¢¤³¤Î¥¹¥È¥ê¡¼¥à¤ËÂФ·¤Æ - ¹Ô¤Ê¤ï¤ì¤ë¡£ - - $CODING ¤Ï #Mnil ¤Ç¤¢¤Ã¤Æ¤â¤è¤¤¡£¤³¤Î¾ì¹ç¤Ï¸½ºß¤Î¥í¥±¡¼¥ë - (LC_CTYPE) ¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤¿¥³¡¼¥É·Ï¤¬»È¤ï¤ì¤ë¡£ - - @return - ¤â¤·½èÍý¤¬À®¸ù¤¹¤ì¤Ð¡¢mconv_stream_converter () ¤Ïºî¤é¤ì¤¿¥³¡¼¥É¥³ - ¥ó¥Ð¡¼¥¿¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code - ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ - - @latexonly \IPAlabel{mconverter} @endlatexonly */ - -/*** - @errors - @c MERROR_SYMBOL, @c MERROR_CODING - - @seealso - mconv_buffer_converter () */ - -MConverter * -mconv_stream_converter (MSymbol name, FILE *fp) -{ - MCodingSystem *coding; - MConverter *converter; - MConverterStatus *internal; - - if (name == Mnil) - name = mlocale_get_prop (mlocale__ctype, Mcoding); - coding = find_coding (name); - if (! coding) - MERROR (MERROR_CODING, NULL); - MSTRUCT_CALLOC (converter, MERROR_CODING); - MSTRUCT_CALLOC (internal, MERROR_CODING); - converter->internal_info = internal; - internal->coding = coding; - if (coding->resetter - && (*coding->resetter) (converter) < 0) - { - free (internal); - free (converter); - MERROR (MERROR_CODING, NULL); - } - - if (fseek (fp, 0, SEEK_CUR) < 0) - { - if (errno == EBADF) - { - free (internal); - free (converter); - return NULL; - } - internal->seekable = 0; - } - else - internal->seekable = 1; - internal->unread = mtext (); - internal->work_mt = mtext (); - mtext__enlarge (internal->work_mt, MAX_UTF8_CHAR_BYTES); - internal->fp = fp; - internal->binding = BINDING_STREAM; - - return converter; -} - -/*=*/ - -/***en - @brief Reset a code converter. - - The mconv_reset_converter () function resets code converter - $CONVERTER to the initial state. - - @return - If $CONVERTER->coding has its own reseter function, - mconv_reset_converter () returns the result of that function - applied to $CONVERTER. Otherwise it returns 0. */ - -/***ja - @brief ¥³¡¼¥É¥³¥ó¥Ð¡¼¥¿¤ò¥ê¥»¥Ã¥È¤¹¤ë - - ´Ø¿ô mconv_reset_converter () ¤Ï¥³¡¼¥É¥³¥ó¥Ð¡¼¥¿ $CONVERTER ¤ò½é´ü - ¾õÂÖ¤ËÌ᤹¡£ - - @return - ¤â¤· $CONVERTER->coding ¤Ë¥ê¥»¥Ã¥ÈÍѤδؿô¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ë¤Ê¤é¤Ð¡¢ - mconv_reset_converter () ¤Ï¤½¤Î´Ø¿ô¤Ë $CONVERTER ¤òŬÍѤ·¤¿·ë²Ì¤ò - ÊÖ¤·¡¢¤½¤¦¤Ç¤Ê¤±¤ì¤Ð0¤òÊÖ¤¹¡£ */ - -int -mconv_reset_converter (MConverter *converter) -{ - MConverterStatus *internal = (MConverterStatus *) converter->internal_info; - - converter->nchars = converter->nbytes = 0; - converter->result = MCONVERSION_RESULT_SUCCESS; - internal->carryover_bytes = 0; - mtext_reset (internal->unread); - if (internal->coding->resetter) - return (*internal->coding->resetter) (converter); - return 0; -} - -/*=*/ - -/***en - @brief Free a code converter. - - The mconv_free_converter () function frees the code converter - $CONVERTER. */ - -/***ja - @brief ¥³¡¼¥É¥³¥ó¥Ð¡¼¥¿¤ò²òÊü¤¹¤ë - - ´Ø¿ô mconv_free_converter () ¤Ï¥³¡¼¥É¥³¥ó¥Ð¡¼¥¿ $CONVERTER ¤ò²òÊü - ¤¹¤ë¡£ */ - -void -mconv_free_converter (MConverter *converter) -{ - MConverterStatus *internal = (MConverterStatus *) converter->internal_info; - - M17N_OBJECT_UNREF (internal->work_mt); - M17N_OBJECT_UNREF (internal->unread); - free (internal); - free (converter); -} - -/*=*/ - -/***en - @brief Bind a buffer to a code converter. - - The mconv_rebind_buffer () function binds buffer area of $N bytes - pointed to by $BUF to code converter $CONVERTER. Subsequent - decodings and encodings are done to/from this newly bound buffer - area. - - @return - This function always returns $CONVERTER. */ - -/***ja - @brief ¥³¡¼¥É¥³¥ó¥Ð¡¼¥¿¤Ë¥Ð¥Ã¥Õ¥¡Îΰè¤ò·ë¤ÓÉÕ¤±¤ë - - ´Ø¿ô mconv_rebind_buffer () ¤Ï¡¢$BUF ¤Ë¤è¤Ã¤Æ»Ø¤µ¤ì¤¿Â礭¤µ $N ¥Ð - ¥¤¥È¤Î¥Ð¥Ã¥Õ¥¡Îΰè¤ò¥³¡¼¥É¥³¥ó¥Ð¡¼¥¿ $CONVERTER ¤Ë·ë¤ÓÉÕ¤±¤ë¡£¤³¤ì - °Ê¹ß¤Î¥Ç¥³¡¼¥É¤ª¤è¤Ó¥¨¥ó¥³¡¼¥É¤Ï¡¢¤³¤Î¿·¤¿¤Ë·ë¤ÓÉÕ¤±¤é¤ì¤¿¥Ð¥Ã¥Õ¥¡ - Îΰè¤ËÂФ·¤Æ¹Ô¤Ê¤ï¤ì¤ë¤è¤¦¤Ë¤Ê¤ë¡£ - - @return - ¤³¤Î´Ø¿ô¤Ï¾ï¤Ë $CONVERTER ¤òÊÖ¤¹¡£ - - @latexonly \IPAlabel{mconv_rebind_buffer} @endlatexonly */ - -/*** - @seealso - mconv_rebind_stream () */ - -MConverter * -mconv_rebind_buffer (MConverter *converter, unsigned char *buf, int n) -{ - MConverterStatus *internal = (MConverterStatus *) converter->internal_info; - - internal->buf = buf; - internal->used = 0; - internal->bufsize = n; - internal->binding = BINDING_BUFFER; - return converter; -} - -/*=*/ - -/***en - @brief Bind a stream to a code converter. - - The mconv_rebind_stream () function binds stream $FP to code - converter $CONVERTER. Following decodings and encodings are done - to/from this newly bound stream. - - @return - This function always returns $CONVERTER. */ - -/***ja - @brief ¥³¡¼¥É¥³¥ó¥Ð¡¼¥¿¤Ë¥¹¥È¥ê¡¼¥à¤ò·ë¤ÓÉÕ¤±¤ë - - ´Ø¿ô mconv_rebind_stream () ¤Ï¡¢¥¹¥È¥ê¡¼¥à $FP ¤ò¥³¡¼¥É¥³¥ó¥Ð¡¼¥¿ - $CONVERTER ¤Ë·ë¤ÓÉÕ¤±¤ë¡£¤³¤ì°Ê¹ß¤Î¥Ç¥³¡¼¥É¤ª¤è¤Ó¥¨¥ó¥³¡¼¥É¤Ï¡¢ - ¤³¤Î¿·¤¿¤Ë·ë¤ÓÉÕ¤±¤é¤ì¤¿¥¹¥È¥ê¡¼¥à¤ËÂФ·¤Æ¹Ô¤Ê¤ï¤ì¤ë¤è¤¦¤Ë¤Ê¤ë¡£ - - @return - ¤³¤Î´Ø¿ô¤Ï¾ï¤Ë $CONVERTER ¤òÊÖ¤¹¡£ - - @latexonly \IPAlabel{mconv_rebind_stream} @endlatexonly */ - -/*** - @seealso - mconv_rebind_buffer () */ - -MConverter * -mconv_rebind_stream (MConverter *converter, FILE *fp) -{ - MConverterStatus *internal = (MConverterStatus *) converter->internal_info; - - if (fseek (fp, 0, SEEK_CUR) < 0) - { - if (errno == EBADF) - return NULL; - internal->seekable = 0; - } - else - internal->seekable = 1; - internal->fp = fp; - internal->binding = BINDING_STREAM; - return converter; -} - -/*=*/ - -/***en - @brief Decode a byte sequence into an M-text. - - The mconv_decode () function decodes a byte sequence and appends - the result at the end of M-text $MT. The source byte sequence is - taken from currently bound the buffer area or the stream. - - @return - If the operation was successful, mconv_decode () returns updated - $MT. Otherwise it returns @c NULL and assigns an error code to - the external variable #merror_code. */ - -/***ja - @brief ¥Ð¥¤¥ÈÎó¤ò M-text ¤Ë¥Ç¥³¡¼¥É¤¹¤ë - - ´Ø¿ô mconv_decode () ¤Ï¡¢¥Ð¥¤¥ÈÎó¤ò¥Ç¥³¡¼¥É¤·¤Æ¤½¤Î·ë²Ì¤ò M-text - $MT ¤ÎËöÈø¤ËÄɲ乤롣¥Ç¥³¡¼¥É¸µ¤Î¥Ð¥¤¥ÈÎó¤Ï¡¢¸½ºß·ë¤ÓÉÕ¤±¤é¤ì¤Æ¤¤¤ë - ¥Ð¥Ã¥Õ¥¡Îΰ褢¤ë¤¤¤Ï¥¹¥È¥ê¡¼¥à¤«¤é¼è¤é¤ì¤ë¡£ - - @return - ¤â¤·½èÍý¤¬À®¸ù¤¹¤ì¤Ð¡¢mconv_decode () ¤Ï¹¹¿·¤µ¤ì¤¿ $MT ¤òÊÖ¤¹¡£¤½ - ¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤ò - ÀßÄꤹ¤ë¡£ */ - -/*** - @errors - @c MERROR_IO, @c MERROR_CODING - - @seealso - mconv_rebind_buffer (), mconv_rebind_stream (), - mconv_encode (), mconv_encode_range (), - mconv_decode_buffer (), mconv_decode_stream () */ - -MText * -mconv_decode (MConverter *converter, MText *mt) -{ - MConverterStatus *internal = (MConverterStatus *) converter->internal_info; - int at_most = converter->at_most > 0 ? converter->at_most : -1; - int n; - - M_CHECK_READONLY (mt, NULL); - - if (! mt->data) - mtext__enlarge (mt, MAX_UTF8_CHAR_BYTES); - - converter->nchars = converter->nbytes = 0; - converter->result = MCONVERSION_RESULT_SUCCESS; - - n = mtext_nchars (internal->unread); - if (n > 0) - { - int limit = n; - int i; - - if (at_most > 0 && at_most < limit) - limit = at_most; - - for (i = 0, n -= 1; i < limit; i++, converter->nchars++, n--) - mtext_cat_char (mt, mtext_ref_char (internal->unread, n)); - mtext_del (internal->unread, n + 1, internal->unread->nchars); - if (at_most > 0) - { - if (at_most == limit) - return mt; - converter->at_most -= converter->nchars; - } - } - - if (internal->binding == BINDING_BUFFER) - { - (*internal->coding->decoder) (internal->buf + internal->used, - internal->bufsize - internal->used, - mt, converter); - internal->used += converter->nbytes; - } - else if (internal->binding == BINDING_STREAM) - { - unsigned char work[CONVERT_WORKSIZE]; - int last_block = converter->last_block; - int use_fread = at_most < 0 && internal->seekable; - - converter->last_block = 0; - while (1) - { - int nbytes, prev_nbytes; - - if (feof (internal->fp)) - nbytes = 0; - else if (use_fread) - nbytes = fread (work, sizeof (unsigned char), CONVERT_WORKSIZE, - internal->fp); - else - { - int c = getc (internal->fp); - - if (c != EOF) - work[0] = c, nbytes = 1; - else - nbytes = 0; - } - - if (ferror (internal->fp)) - { - converter->result = MCONVERSION_RESULT_IO_ERROR; - break; - } - - if (nbytes == 0) - converter->last_block = last_block; - prev_nbytes = converter->nbytes; - (*internal->coding->decoder) (work, nbytes, mt, converter); - if (converter->nbytes - prev_nbytes < nbytes) - { - if (use_fread) - fseek (internal->fp, converter->nbytes - prev_nbytes - nbytes, - SEEK_CUR); - else - ungetc (work[0], internal->fp); - break; - } - if (nbytes == 0 - || (converter->at_most > 0 - && converter->nchars == converter->at_most)) - break; - } - converter->last_block = last_block; - } - else /* internal->binding == BINDING_NONE */ - MERROR (MERROR_CODING, NULL); - - converter->at_most = at_most; - return ((converter->result == MCONVERSION_RESULT_SUCCESS - || converter->result == MCONVERSION_RESULT_INSUFFICIENT_SRC) - ? mt : NULL); -} - -/*=*/ - -/***en - @brief Decode a buffer area based on a coding system. - - The mconv_decode_buffer () function decodes $N bytes of buffer - area pointed to by $BUF based on the coding system $NAME. A - temporary code converter for decoding is automatically created - and freed. - - @return - If the operation was successful, mconv_decode_buffer () returns - the resulting M-text. Otherwise it returns NULL and assigns an - error code to the external variable #merror_code. */ - -/***ja - @brief ¥³¡¼¥É·Ï¤Ë´ð¤Å¤¤¤Æ¥Ð¥Ã¥Õ¥¡Îΰè¤ò¥Ç¥³¡¼¥É¤¹¤ë - - ´Ø¿ô mconv_decode_buffer () ¤Ï¡¢$BUF ¤Ë¤è¤Ã¤Æ»Ø¤µ¤ì¤¿ $N ¥Ð¥¤¥È¤Î - ¥Ð¥Ã¥Õ¥¡Îΰè¤ò¡¢¥³¡¼¥É·Ï $NAME ¤Ë´ð¤Å¤¤¤Æ¥Ç¥³¡¼¥É¤¹¤ë¡£¥Ç¥³¡¼¥É¤Ë - ɬÍפʥ³¡¼¥É¥³¥ó¥Ð¡¼¥¿¤ÎºîÀ®¤È²òÊü¤Ï¼«Æ°Åª¤Ë¹Ô¤Ê¤ï¤ì¤ë¡£ - - @return - ¤â¤·½èÍý¤¬À®¸ù¤¹¤ì¤Ð¡¢mconv_decode_buffer () ¤ÏÆÀ¤é¤ì¤¿ M-text ¤ò - ÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼ - ¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ */ - -/*** - @errors - @c MERROR_IO, @c MERROR_CODING - - @seealso - mconv_decode (), mconv_decode_stream () */ - -MText * -mconv_decode_buffer (MSymbol name, unsigned char *buf, int n) -{ - MConverter *converter = mconv_buffer_converter (name, buf, n); - MText *mt; - - if (! converter) - return NULL; - mt = mtext (); - if (! mconv_decode (converter, mt)) - { - M17N_OBJECT_UNREF (mt); - mt = NULL; - } - mconv_free_converter (converter); - return mt; -} - -/*=*/ - -/***en - @brief Decode a stream input based on a coding system. - - The mconv_decode_stream () function decodes the entire byte - sequence read in from stream $FP based on the coding system $NAME. - A code converter for decoding is automatically created and freed. - - @return - If the operation was successful, mconv_decode_stream () returns - the resulting M-text. Otherwise it returns NULL and assigns an - error code to the external variable #merror_code. */ - -/***ja - @brief ¥³¡¼¥É·Ï¤Ë´ð¤Å¤¤¤Æ¥¹¥È¥ê¡¼¥àÆþÎϤò¥Ç¥³¡¼¥É¤¹¤ë - - ´Ø¿ô mconv_decode_stream () ¤Ï¡¢¥¹¥È¥ê¡¼¥à $FP ¤«¤éÆɤ߹þ¤Þ¤ì¤ë¥Ð - ¥¤¥ÈÎóÁ´ÂΤò¡¢¥³¡¼¥É·Ï $NAME ¤Ë´ð¤Å¤¤¤Æ¥Ç¥³¡¼¥É¤¹¤ë¡£¥Ç¥³¡¼¥É¤Ëɬ - Íפʥ³¡¼¥É¥³¥ó¥Ð¡¼¥¿¤ÎºîÀ®¤È²òÊü¤Ï¼«Æ°Åª¤Ë¹Ô¤Ê¤ï¤ì¤ë¡£ - - @return - ¤â¤·½èÍý¤¬À®¸ù¤¹¤ì¤Ð¡¢mconv_decode_stream () ¤ÏÆÀ¤é¤ì¤¿ M-text ¤òÊÖ - ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼ - ¥É¤òÀßÄꤹ¤ë¡£ */ - -/*** - @errors - @c MERROR_IO, @c MERROR_CODING - - @seealso - mconv_decode (), mconv_decode_buffer () */ - -MText * -mconv_decode_stream (MSymbol name, FILE *fp) -{ - MConverter *converter = mconv_stream_converter (name, fp); - MText *mt; - - if (! converter) - return NULL; - mt = mtext (); - if (! mconv_decode (converter, mt)) - { - M17N_OBJECT_UNREF (mt); - mt = NULL; - } - mconv_free_converter (converter); - return mt; -} - -/*=*/ - -/***en @brief Encode an M-text into a byte sequence. - - The mconv_encode () function encodes M-text $MT and writes the - resulting byte sequence into the buffer area or the stream that is - currently bound to code converter $CONVERTER. - - @return - If the operation was successful, mconv_encode () returns the - number of written bytes. Otherwise it returns -1 and assigns an - error code to the external variable #merror_code. */ - -/***ja - @brief M-text ¤ò¥Ð¥¤¥ÈÎó¤Ë¥¨¥ó¥³¡¼¥É¤¹¤ë - - ´Ø¿ô mconv_encode () ¤Ï¡¢M-text $MT ¤ò¥¨¥ó¥³¡¼¥É¤·¤Æ¡¢¥³¡¼¥É¥³¥ó¥Ð¡¼ - ¥¿ $CONVERTER ¤Ë¸½ºß·ë¤ÓÉÕ¤±¤é¤ì¤Æ¤¤¤ë¥Ð¥Ã¥Õ¥¡Îΰ褢¤ë¤¤¤Ï¥¹¥È¥ê¡¼ - ¥à¤Ë½ñ¤­¹þ¤à¡£ - - @return - ¤â¤·½èÍý¤¬À®¸ù¤¹¤ì¤Ð¡¢mconv_encode () ¤Ï½ñ¤­¹þ¤Þ¤ì¤¿¥Ð¥¤¥È¿ô¤òÊÖ¤¹¡£ - ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄê - ¤¹¤ë¡£ */ - -/*** - @errors - @c MERROR_IO, @c MERROR_CODING - - @seealso - mconv_rebind_buffer (), mconv_rebind_stream(), - mconv_decode (), mconv_encode_range () */ - -int -mconv_encode (MConverter *converter, MText *mt) -{ - return mconv_encode_range (converter, mt, 0, mtext_nchars (mt)); -} - -/*=*/ - -/***en - @brief Encode a part of an M-text - - The mconv_encode_range () function encodes the text between $FROM - (inclusive) and $TO (exclusive) in M-text $MT and writes the - resulting byte sequence into the buffer area or the stream that is - currently bound to code converter $CONVERTER. - - @return - If the operation was successful, mconv_encode_range () returns the - number of written bytes. Otherwise it returns -1 and assigns an - error code to the external variable #merror_code. */ - -/***ja - @brief M-text ¤Î°ìÉô¤ò¤ò¥Ð¥¤¥ÈÎó¤Ë¥¨¥ó¥³¡¼¥É¤¹¤ë - - ´Ø¿ô mconv_encode_range () ¤Ï¡¢M-text $MT ¤Î $FROM ¡Ê´Þ¤à¡Ë¤«¤é - $TO ¡Ê´Þ¤Þ¤Ê¤¤¡Ë¤Þ¤Ç¤ÎÈϰϤΥƥ­¥¹¥È¤ò¥¨¥ó¥³¡¼¥É¤·¤Æ¡¢¥³¡¼¥É¥³¥ó¥Ð¡¼ - ¥¿ $CONVERTER ¤Ë¸½ºß·ë¤ÓÉÕ¤±¤é¤ì¤Æ¤¤¤ë¥Ð¥Ã¥Õ¥¡Îΰ褢¤ë¤¤¤Ï¥¹¥È¥ê¡¼ - ¥à¤Ë½ñ¤­¹þ¤à¡£ - - @return - ¤â¤·½èÍý¤¬À®¸ù¤¹¤ì¤Ð¡¢mconv_encode_range () ¤Ï½ñ¤­¹þ¤Þ¤ì¤¿¥Ð¥¤¥È¿ô - ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼ - ¥É¤òÀßÄꤹ¤ë¡£ */ - -/*** - @errors - @c MERROR_RANGE, @c MERROR_IO, @c MERROR_CODING - - @seealso - mconv_rebind_buffer (), mconv_rebind_stream(), - mconv_decode (), mconv_encode () */ - -int -mconv_encode_range (MConverter *converter, MText *mt, int from, int to) -{ - MConverterStatus *internal = (MConverterStatus *) converter->internal_info; - - M_CHECK_POS_X (mt, from, -1); - M_CHECK_POS_X (mt, to, -1); - if (to < from) - to = from; - - if (converter->at_most > 0 && from + converter->at_most < to) - to = from + converter->at_most; - - converter->nchars = converter->nbytes = 0; - converter->result = MCONVERSION_RESULT_SUCCESS; - - if (internal->binding == BINDING_BUFFER) - { - (*internal->coding->encoder) (mt, from, to, - internal->buf + internal->used, - internal->bufsize - internal->used, - converter); - internal->used += converter->nbytes; - } - else if (internal->binding == BINDING_STREAM) - { - unsigned char work[CONVERT_WORKSIZE]; - - while (from < to) - { - int written = 0; - int prev_nbytes = converter->nbytes; - int this_nbytes; - - (*internal->coding->encoder) (mt, from, to, work, - CONVERT_WORKSIZE, converter); - this_nbytes = converter->nbytes - prev_nbytes; - while (written < this_nbytes) - { - int wrtn = fwrite (work + written, sizeof (unsigned char), - this_nbytes - written, internal->fp); - - if (ferror (internal->fp)) - break; - written += wrtn; - } - if (written < this_nbytes) - { - converter->result = MCONVERSION_RESULT_IO_ERROR; - break; - } - from += converter->nchars; - } - } - else /* fail safe */ - MERROR (MERROR_CODING, -1); - - return ((converter->result == MCONVERSION_RESULT_SUCCESS - || converter->result == MCONVERSION_RESULT_INSUFFICIENT_DST) - ? converter->nbytes : -1); -} - -/*=*/ - -/***en - @brief Encode an M-text into a buffer area. - - The mconv_encode_buffer () function encodes M-text $MT based on - coding system $NAME and writes the resulting byte sequence into the - buffer area pointed to by $BUF. At most $N bytes are written. A - temporary code converter for encoding is automatically created - and freed. - - @return - If the operation was successful, mconv_encode_buffer () returns - the number of written bytes. Otherwise it returns -1 and assigns - an error code to the external variable #merror_code. */ - -/***ja - @brief M-text ¤ò¥¨¥ó¥³¡¼¥É¤·¤Æ¥Ð¥Ã¥Õ¥¡Îΰè¤Ë½ñ¤­¹þ¤à - - ´Ø¿ô mconv_encode_buffer () ¤ÏM-text $MT ¤ò¥³¡¼¥É·Ï $NAME ¤Ë´ð¤Å¤¤ - ¤Æ¥¨¥ó¥³¡¼¥É¤·¡¢ÆÀ¤é¤ì¤¿¥Ð¥¤¥ÈÎó¤ò $BUF ¤Î»Ø¤¹¥Ð¥Ã¥Õ¥¡Îΰè¤Ë½ñ¤­¹þ - ¤à¡£$N ¤Ï½ñ¤­¹þ¤àºÇÂç¥Ð¥¤¥È¿ô¤Ç¤¢¤ë¡£¥¨¥ó¥³¡¼¥É¤ËɬÍפʥ³¡¼¥É¥³¥ó - ¥Ð¡¼¥¿¤ÎºîÀ®¤È²òÊü¤Ï¼«Æ°Åª¤Ë¹Ô¤Ê¤ï¤ì¤ë¡£ - - @return - ¤â¤·½èÍý¤¬À®¸ù¤¹¤ì¤Ð¡¢mconv_encode_buffer () ¤Ï½ñ¤­¹þ¤Þ¤ì¤¿¥Ð¥¤¥È - ¿ô¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð-1¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼ - ¥É¤òÀßÄꤹ¤ë¡£ */ - -/*** - @errors - @c MERROR_IO, @c MERROR_CODING - - @seealso - mconv_encode (), mconv_encode_stream () */ - -int -mconv_encode_buffer (MSymbol name, MText *mt, unsigned char *buf, int n) -{ - MConverter *converter = mconv_buffer_converter (name, buf, n); - int ret; - - if (! converter) - return -1; - ret = mconv_encode (converter, mt); - mconv_free_converter (converter); - return ret; -} - -/*=*/ - -/***en - @brief Encode an M-text to write to a stream. - - The mconv_encode_stream () function encodes M-text $MT based on - coding system $NAME and writes the resulting byte sequence to - stream $FP. A temporary code converter for encoding is - automatically created and freed. - - @return - If the operation was successful, mconv_encode_stream () returns - the number of written bytes. Otherwise it returns -1 and assigns - an error code to the external variable #merror_code. */ - -/***ja - @brief M-text ¤ò¥¨¥ó¥³¡¼¥É¤·¤Æ¥¹¥È¥ê¡¼¥à¤Ë½ñ¤­¹þ¤à - - ´Ø¿ô mconv_encode_stream () ¤ÏM-text $MT ¤ò¥³¡¼¥É·Ï $NAME ¤Ë´ð¤Å¤¤ - ¤Æ¥¨¥ó¥³¡¼¥É¤·¡¢ÆÀ¤é¤ì¤¿¥Ð¥¤¥ÈÎó¤ò¥¹¥È¥ê¡¼¥à $FP ¤Ë½ñ¤­½Ð¤¹¡£¥¨¥ó - ¥³¡¼¥É¤ËɬÍפʥ³¡¼¥É¥³¥ó¥Ð¡¼¥¿¤ÎºîÀ®¤È²òÊü¤Ï¼«Æ°Åª¤Ë¹Ô¤Ê¤ï¤ì¤ë¡£ - - @return - ¤â¤·½èÍý¤¬À®¸ù¤¹¤ì¤Ð¡¢mconv_encode_stream () ¤Ï½ñ¤­¹þ¤Þ¤ì¤¿¥Ð¥¤¥È¿ô - ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð-1¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É - ¤òÀßÄꤹ¤ë¡£ */ - -/*** - @errors - @c MERROR_IO, @c MERROR_CODING - - @seealso - mconv_encode (), mconv_encode_buffer (), mconv_encode_file () */ - -int -mconv_encode_stream (MSymbol name, MText *mt, FILE *fp) -{ - MConverter *converter = mconv_stream_converter (name, fp); - int ret; - - if (! converter) - return -1; - ret = mconv_encode (converter, mt); - mconv_free_converter (converter); - return ret; -} - -/*=*/ - -/***en - @brief Read a character via a code converter. - - The mconv_getc () function reads one character from the buffer - area or the stream that is currently bound to code converter - $CONVERTER. The decoder of $CONVERTER is used to decode the byte - sequence. The internal status of $CONVERTER is updated - appropriately. - - @return - If the operation was successful, mconv_getc () returns the - character read in. If the input source reaches EOF, it returns @c - EOF without changing the external variable #merror_code. If an - error is detected, it returns @c EOF and assigns an error code to - #merror_code. */ - -/***ja - @brief ¥³¡¼¥É¥³¥ó¥Ð¡¼¥¿·Ðͳ¤Ç1ʸ»úÆɤà - - ´Ø¿ô mconv_getc () ¤Ï¡¢¥³¡¼¥É¥³¥ó¥Ð¡¼¥¿ $CONVERTER ¤Ë¸½ºß·ë¤ÓÉÕ¤± - ¤é¤ì¤Æ¤¤¤ë¥Ð¥Ã¥Õ¥¡Îΰ褢¤ë¤¤¤Ï¥¹¥È¥ê¡¼¥à¤«¤é1ʸ»ú¤òÆɤ߹þ¤à¡£¥Ð¥¤ - ¥ÈÎó¤Î¥Ç¥³¡¼¥É¤Ë¤Ï $CONVERTER ¤Î¥Ç¥³¡¼¥À¤¬ÍѤ¤¤é¤ì¤ë¡£$CONVERTER - ¤ÎÆâÉô¾õÂÖ¤ÏɬÍפ˱þ¤¸¤Æ¹¹¿·¤µ¤ì¤ë¡£ - - @return - ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¡¢mconv_getc () ¤ÏÆɤ߹þ¤Þ¤ì¤¿Ê¸»ú¤òÊÖ¤¹¡£ÆþÎϸ»¤¬ - EOF ¤Ë㤷¤¿¾ì¹ç¤Ï¡¢³°ÉôÊÑ¿ô #merror_code ¤òÊѤ¨¤º¤Ë @c EOF ¤òÊÖ¤¹¡£ - ¥¨¥é¡¼¤¬¸¡½Ð¤µ¤ì¤¿¾ì¹ç¤Ï @c EOF ¤òÊÖ¤·¡¢#merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É - ¤òÀßÄꤹ¤ë¡£ */ - -/*** - @errors - @c MERROR_CODING - - @seealso - mconv_ungetc (), mconv_putc (), mconv_gets () */ - -int -mconv_getc (MConverter *converter) -{ - MConverterStatus *internal = (MConverterStatus *) converter->internal_info; - int at_most = converter->at_most; - - mtext_reset (internal->work_mt); - converter->at_most = 1; - mconv_decode (converter, internal->work_mt); - converter->at_most = at_most; - return (converter->nchars == 1 - ? STRING_CHAR (internal->work_mt->data) - : EOF); -} - -/*=*/ - -/***en - @brief Push a character back to a code converter. - - The mconv_ungetc () function pushes character $C back to code - converter $CONVERTER. Any number of characters can be pushed - back. The lastly pushed back character is firstly read by the - subsequent mconv_getc () call. The characters pushed back are - registered only in $CONVERTER; they are not written to the input - source. The internal status of $CONVERTER is updated - appropriately. - - @return - If the operation was successful, mconv_ungetc () returns $C. - Otherwise it returns @c EOF and assigns an error code to the - external variable #merror_code. */ - -/***ja - @brief ¥³¡¼¥É¥³¥ó¥Ð¡¼¥¿¤Ë1ʸ»úÌ᤹ - - ´Ø¿ô mconv_ungetc () ¤Ï¡¢¥³¡¼¥É¥³¥ó¥Ð¡¼¥¿ $CONVERTER ¤Ëʸ»ú $C ¤ò - ²¡¤·Ì᤹¡£²¡¤·Ì᤻¤ëʸ»ú¿ô¤ËÀ©¸Â¤Ï¤Ê¤¤¡£¤³¤Î¸å¤Ë mconv_getc () ¤ò - ¸Æ¤Ó½Ð¤¹¤È¡¢ºÇ¸å¤ËÌᤵ¤ì¤¿Ê¸»ú¤¬ºÇ½é¤ËÆɤޤì¤ë¡£²¡¤·Ìᤵ¤ì¤¿Ê¸»ú¤Ï - $CONVERTER ¤ÎÆâÉô¤ËÃߤ¨¤é¤ì¤ë¤À¤±¤Ç¤¢¤ê¡¢¼ÂºÝ¤ËÆþÎϸ»¤Ë½ñ¤­¹þ¤Þ¤ì - ¤ë¤ï¤±¤Ç¤Ï¤Ê¤¤¡£$CONVERTER ¤ÎÆâÉô¾õÂÖ¤ÏɬÍפ˱þ¤¸¤Æ¹¹¿·¤µ¤ì¤ë¡£ - - @return - ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¡¢mconv_ungetc () ¤Ï $C ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c - EOF ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ */ - -/*** - @errors - @c MERROR_CODING, @c MERROR_CHAR - - @seealso - mconv_getc (), mconv_putc (), mconv_gets () */ - -int -mconv_ungetc (MConverter *converter, int c) -{ - MConverterStatus *internal = (MConverterStatus *) converter->internal_info; - - M_CHECK_CHAR (c, EOF); - - converter->result = MCONVERSION_RESULT_SUCCESS; - mtext_cat_char (internal->unread, c); - return c; -} - -/*=*/ - -/***en - @brief Write a character via a code converter. - - The mconv_putc () function writes character $C to the buffer area - or the stream that is currently bound to code converter - $CONVERTER. The encoder of $CONVERTER is used to encode the - character. The number of bytes actually written is set to the @c - nbytes member of $CONVERTER. The internal status of $CONVERTER - is updated appropriately. - - @return - If the operation was successful, mconv_putc () returns $C. - If an error is detected, it returns @c EOF and assigns - an error code to the external variable #merror_code. */ - -/***ja - @brief ¥³¡¼¥É¥³¥ó¥Ð¡¼¥¿¤ò·Ðͳ¤Ç1ʸ»ú½ñ¤¯ - - ´Ø¿ô mconv_putc () ¤Ï¡¢¥³¡¼¥É¥³¥ó¥Ð¡¼¥¿ $CONVERTER ¤Ë¸½ºß·ë¤ÓÉÕ¤± - ¤é¤ì¤Æ¤¤¤ë¥Ð¥Ã¥Õ¥¡Îΰ褢¤ë¤¤¤Ï¥¹¥È¥ê¡¼¥à¤Ëʸ»ú $C ¤ò½ñ¤­½Ð¤¹¡£Ê¸»ú - ¤Î¥¨¥ó¥³¡¼¥É¤Ë¤Ï $CONVERTER ¤Î¥¨¥ó¥³¡¼¥À¤¬ÍѤ¤¤é¤ì¤ë¡£¼ÂºÝ¤Ë½ñ¤­½Ð - ¤µ¤ì¤¿¥Ð¥¤¥È¿ô¤Ï¡¢$CONVERTER ¤Î ¥á¥ó¥Ð¡¼ @c nbytes ¤Ë¥»¥Ã¥È¤µ¤ì¤ë¡£ - $CONVERTER ¤ÎÆâÉô¾õÂÖ¤ÏɬÍפ˱þ¤¸¤Æ¹¹¿·¤µ¤ì¤ë¡£ - - @return - ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¡¢mconv_putc () ¤Ï $C ¤òÊÖ¤¹¡£¥¨¥é¡¼¤¬¸¡½Ð¤µ¤ì¤¿¾ì¹ç - ¤Ï @c EOF ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ */ - -/*** - @errors - @c MERROR_CODING, @c MERROR_IO, @c MERROR_CHAR - - @seealso - mconv_getc (), mconv_ungetc (), mconv_gets () */ - -int -mconv_putc (MConverter *converter, int c) -{ - MConverterStatus *internal = (MConverterStatus *) converter->internal_info; - - M_CHECK_CHAR (c, EOF); - mtext_reset (internal->work_mt); - mtext_cat_char (internal->work_mt, c); - if (mconv_encode_range (converter, internal->work_mt, 0, 1) < 0) - return EOF; - return c; -} - -/*=*/ - -/***en - @brief Read a line using a code converter. - - The mconv_gets () function reads one line from the buffer area or - the stream that is currently bound to code converter $CONVERTER. - The decoder of $CONVERTER is used for decoding. The decoded - character sequence is appended at the end of M-text $MT. The - final newline character in the original byte sequence is not - appended. The internal status of $CONVERTER is updated - appropriately. - - @return - If the operation was successful, mconv_gets () returns the - modified $MT. If it encounters EOF without reading a single - character, it returns $MT without changing it. If an error is - detected, it returns @c NULL and assigns an error code to @c - merror_code. */ - -/***ja - @brief ¥³¡¼¥É¥³¥ó¥Ð¡¼¥¿¤ò»È¤Ã¤Æ1¹ÔÆɤà - - ´Ø¿ô mconv_gets () ¤Ï¡¢¥³¡¼¥É¥³¥ó¥Ð¡¼¥¿ $CONVERTER ¤Ë¸½ºß·ë¤ÓÉÕ¤± - ¤é¤ì¤Æ¤¤¤ë¥Ð¥Ã¥Õ¥¡Îΰ褢¤ë¤¤¤Ï¥¹¥È¥ê¡¼¥à¤«¤é1¹Ô¤òÆɤ߹þ¤à¡£¥Ð¥¤¥È - Îó¤Î¥Ç¥³¡¼¥É¤Ë¤Ï $CONVERTER ¤Î¥Ç¥³¡¼¥À¤¬ÍѤ¤¤é¤ì¤ë¡£¥Ç¥³¡¼¥É¤µ¤ì¤¿ - ʸ»úÎó¤Ï M-text $MT ¤ÎËöÈø¤ËÄɲ䵤ì¤ë¡£¸µ¤Î¥Ð¥¤¥ÈÎó¤Î½ªÃ¼²þ¹Ôʸ»ú - ¤ÏÄɲ䵤ì¤Ê¤¤¡£$CONVERTER ¤ÎÆâÉô¾õÂÖ¤ÏɬÍפ˱þ¤¸¤Æ¹¹¿·¤µ¤ì¤ë¡£ - - @return - ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¡¢mconv_gets () ¤ÏÊѹ¹¤µ¤ì¤¿ $MT ¤òÊÖ¤¹¡£¤â¤·1ʸ»ú - ¤âÆɤޤº¤Ë EOF ¤ËÅö¤¿¤Ã¤¿¾ì¹ç¤Ï¡¢$MT ¤òÊѹ¹¤»¤º¤Ë¤½¤Î¤Þ¤ÞÊÖ¤¹¡£¥¨ - ¥é¡¼¤¬¸¡½Ð¤µ¤ì¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤·¡¢#merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤ò - ÀßÄꤹ¤ë¡£ */ - -/*** - @errors - @c MERROR_CODING - - @seealso - mconv_getc (), mconv_ungetc (), mconv_putc () */ - -MText * -mconv_gets (MConverter *converter, MText *mt) -{ - int c; - - M_CHECK_READONLY (mt, NULL); - while (1) - { - c = mconv_getc (converter); - if (c == EOF || c == '\n') - break; - mtext_cat_char (mt, c); - } - if (c == EOF && converter->result != MCONVERSION_RESULT_SUCCESS) - /* mconv_getc () sets merror_code */ - return NULL; - return mt; -} - -/*=*/ - -/*** @} */ - -/* - Local Variables: - coding: euc-japan - End: -*/ diff --git a/src/coding.h b/src/coding.h deleted file mode 100644 index cb256e6..0000000 --- a/src/coding.h +++ /dev/null @@ -1,31 +0,0 @@ -/* coding.h -- header file for the code conversion module. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -#ifndef _M17N_CODING_H_ -#define _M17N_CODING_H_ - -extern void mconv__define_coding_from_charset (MSymbol sym); -extern void mconv__register_charset_coding (MSymbol name); - -extern int mcoding__load_from_database (); - -#endif /* _M17N_CODING_H_ */ diff --git a/src/database.c b/src/database.c deleted file mode 100644 index 4f83f8f..0000000 --- a/src/database.c +++ /dev/null @@ -1,852 +0,0 @@ -/* database.c -- database module. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -/***en - @addtogroup m17nDatabase - @brief The m17n database and API for it - - The m17n library dynamically acquires various kinds of information - in need from data in the m17n database. Application - programs can also add/load their original data to/from the m17n - database. The m17n database contains multiple heterogeneous data, - and each data is identified by four tags; TAG1, TAG2, TAG3, TAG4. - Each tag must be a symbol. - - TAG1 specifies the type of data stored in the database as below. - -
    - -
  • If TAG1 is #Mchar_table, the data is of the @e chartable @e - type and provides information about each character. In this case, - TAG2 specifies the type of the information and must be #Msymbol, - #Minteger, #Mstring, #Mtext, or #Mplist. TAG3 and TAG4 can be any - symbols. - -
  • If TAG1 is #Mcharset, the data is of the @e charset @e type - and provides a decode/encode mapping table for a charset. In this - case, TAG2 must be a symbol representing a charset. TAG3 and TAG4 - can be any symbols. - -
  • If TAG1 is neither #Mchar_table nor #Mcharset, the data is of - the @e plist @e type. See the documentation of the mdatabase_load - () function for the details. In this case, TAG2, TAG3, and TAG4 - can be any symbols. - -
- - Below, the notation \ means a data with - those tags. - - Application programs first calls the mdatabase_find () function to - get a pointer to an object of the type #MDatabase. That object - holds information about the specified data. When it is - successfully returned, the mdatabase_load () function loads the - data. The implementation of the structure #MDatabase is - concealed from application programs. -*/ - -/***ja - @addtogroup m17nDatabase - @brief ¸À¸ì¾ðÊó¥Ù¡¼¥¹¤Ë¤È¤½¤ì¤Ë´Ø¤¹¤ë API - - m17n ¥é¥¤¥Ö¥é¥ê¤ÏɬÍפ˱þ¤¸¤ÆưŪ¤Ë m17n ¸À¸ì¾ðÊó¥Ù¡¼¥¹¤«¤é¥Ç¡¼¥¿ - ¤ò¼èÆÀ¤¹¤ë¡£¤Þ¤¿¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤âÆȼ«¤Î¥Ç¡¼¥¿¤ò m17n - ¸À¸ì¾ðÊó¥Ù¡¼¥¹¤ËÄɲä·¡¢¤½¤ì¤òưŪ¤Ë¼èÆÀ¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¡£m17n ¸À - ¸ì¾ðÊó¥Ù¡¼¥¹¤ÏÊ£¿ô¤Î¥Ç¡¼¥¿¥Ù¡¼¥¹¤«¤é¤Ê¤ê¡¢³Æ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ï£´¤Ä¤Î¥¿ - ¥° TAG1, TAG2, TAG3, TAG4¡Ê¤¹¤Ù¤Æ¥·¥ó¥Ü¥ë¡Ë¤Ë¤è¤Ã¤Æ¼±Ê̤µ¤ì¤ë¡£ - - TAG1 ¤Ï¥Ç¡¼¥¿¥Ù¡¼¥¹Æâ¤Î¥Ç¡¼¥¿¤Î¥¿¥¤¥×¤ò¼¨¤¹¡£ - - TAG1 ¤¬ #Mchar_table ¤Î¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ï @e chartable¥¿¥¤¥× ¤È¸Æ¤Ð¤ì¡¢ - ³Æʸ»ú¤Ë´Ø¤¹¤ë¾ðÊó¤òÄ󶡤¹¤ë¡£¤³¤Î¾ì¹ç TAG2 ¤Ï¾ðÊó¤Î¼ïÎà¤ò»ØÄꤹ¤ë - ¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢°Ê²¼¤Î¤¤¤º¤ì¤«¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ - - @li #Msymbol @li #Minteger @li #Mstring @li #Mtext @li #Mplist - - TAG3 ¤È TAG4 ¤ÏǤ°Õ¤Î¥·¥ó¥Ü¥ë¤Ç¤è¤¤¡£ - - TAG1 ¤¬ #Mcharset ¤Î¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ï @e charset¥¿¥¤¥× ¤È¸Æ¤Ð¤ì¡¢Ê¸ - »ú¥»¥Ã¥ÈÍѤΥǥ³¡¼¥É¡¿¥¨¥ó¥³¡¼¥É¥Þ¥Ã¥×¤òÄ󶡤¹¤ë¡£¤³¤Î¾ì¹ç TAG2 ¤Ï - ʸ»ú¥»¥Ã¥È¤Î¥·¥ó¥Ü¥ë¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£TAG3 ¤È TAG4 ¤ÏǤ°Õ¤Î¥·¥ó - ¥Ü¥ë¤Ç¤è¤¤¡£ - - TAG1 ¤¬ #Mchar_table ¤Ç¤â #Mcharset ¤Ç¤â¤Ê¤¤¾ì¹ç¡¢¤½¤Î¥Ç¡¼¥¿¥Ù¡¼ - ¥¹¤Ï @e plist ¥¿¥¤¥× ¤È¸Æ¤Ð¤ì¤ë¡£¾ÜºÙ¤Ë´Ø¤·¤Æ¤Ï´Ø¿ô mdatabase_load - () ¤ÎÀâÌÀ¤ò»²¾È¤Î¤³¤È¡£¤³¤Î¾ì¹ç TAG2¡¢TAG3¡¢TAG4 ¤ÏǤ°Õ¤Î¥·¥ó¥Ü¥ë - ¤Ç¤è¤¤¡£ - - °Ê²¼¡¢ÆÃÄê¤Î¥¿¥°¤ò»ý¤Ä¥Ç¡¼¥¿¥Ù¡¼¥¹¤ò \ ¤È¤¤ - ¤¦·Á¼°¤Çɽ¤ï¤¹¡£ - - ¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¡¢¤Þ¤º´Ø¿ô mdatabase_find () »È¤Ã¤Æ¥Ç¡¼ - ¥¿¥Ù¡¼¥¹¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÝ»ý¤¹¤ë¥ª¥Ö¥¸¥§¥¯¥È¡Ê#MDatabase ·¿¡Ë¤Ø¤Î - ¥Ý¥¤¥ó¥¿¤òÆÀ¤ë¡£¤½¤ì¤ËÀ®¸ù¤·¤¿¤é¡¢ mdatabase_load () ¤Ë¤è¤Ã¤Æ¼ÂºÝ - ¤Ë¥Ç¡¼¥¿¥Ù¡¼¥¹¤ò¥í¡¼¥É¤¹¤ë¡£¹½Â¤ÂÎ #MDatabase ¼«¿È¤¬¤É¤¦¼ÂÁõ¤µ¤ì - ¤Æ¤¤¤ë¤«¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤«¤é¤Ï¸«¤¨¤Ê¤¤¡£ - - @latexonly \IPAlabel{database} @endlatexonly -*/ - -/*=*/ - -#if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE) -/*** @addtogroup m17nInternal - @{ */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "m17n.h" -#include "m17n-misc.h" -#include "internal.h" -#include "mtext.h" -#include "character.h" -#include "charset.h" -#include "database.h" -#include "coding.h" -#include "plist.h" - -/** The file containing a list of databases. */ -#define MDB_DIR "mdb.dir" -#define MDB_DIR_LEN 8 - -/** List of database directories. */ -static MPlist *mdb_dir_list; - -/** Structure for a data in the m17n database. */ - -struct MDatabase -{ - /** Tags to identify the data. [0] specifies the type of - database. If it is #Mchar_table, the type is @e chartable, if - it is #Mcharset, the type is @e charset, otherwise the type is - @e plist. */ - MSymbol tag[4]; - - void *(*loader) (MSymbol *tags, void *extra_info); - - /** The meaning of the value is dependent on . If - is load_database (), the value is a string of the file name that - contains the data. */ - void *extra_info; -}; - -/** List of all data. */ -struct MDatabaseList -{ - int size, inc, used; - MDatabase *mdbs; -}; - -static struct MDatabaseList mdb_list; - - -static int -read_number (char *buf, int *i) -{ - int idx = *i; - int c = buf[idx++]; - int n; - - if (!c) - return -1; - - while (c && isspace (c)) c = buf[idx++]; - - if (c == '0') - { - if (buf[idx] == 'x') - { - for (idx++, c = 0; (n = hex_mnemonic[(unsigned) buf[idx]]) < 16; - idx++) - c = (c << 4) | n; - *i = idx; - return c; - } - c = 0; - } - else if (c == '\'') - { - c = buf[idx++]; - if (c == '\\') - { - c = buf[idx++]; - n = escape_mnemonic[c]; - if (n != 255) - c = n; - } - while (buf[idx] && buf[idx++] != '\''); - *i = idx; - return c; - } - else if (hex_mnemonic[c] < 10) - c -= '0'; - else - return -1; - - while ((n = hex_mnemonic[(unsigned) buf[idx]]) < 10) - c = (c * 10) + n, idx++; - *i = idx; - return c; -} - - -/** Load a data of type @c chartable from the file FD, and return the - newly created chartable. */ - -static void * -load_chartable (FILE *fp, MSymbol type) -{ - int c, from, to; - char buf[1024]; - void *val; - MCharTable *table; - - if (! fp) - MERROR (MERROR_DB, NULL); - - table = mchartable (type, (type == Msymbol ? (void *) Mnil - : type == Minteger ? (void *) -1 - : NULL)); - - while (! feof (fp)) - { - int i, len; - - for (len = 0; len < 1023 && (c = getc (fp)) != EOF && c != '\n'; len++) - buf[len] = c; - buf[len] = '\0'; - if (hex_mnemonic[(unsigned) buf[0]] >= 10) - /* skip comment/invalid line */ - continue; - i = 0; - from = read_number (buf, &i); - if (buf[i] == '-') - i++, to = read_number (buf, &i); - else - to = from; - if (from < 0 || to < 0) - goto label_error; - - while (buf[i] && isspace ((unsigned) buf[i])) i++; - c = buf[i]; - if (!c) - break; - - if (type == Mstring) - { - /* VAL is a C-string. */ - if (! (val = strdup (buf + i))) - MEMORY_FULL (MERROR_DB); - } - else if (type == Minteger) - { - /* VAL is an integer. */ - int positive = 1; - int n; - - if (c == '-') - i++, positive = -1; - n = read_number (buf, &i); - if (n < 0) - goto label_error; - val = (void *) (n * positive); - } - else if (type == Mtext) - { - /* VAL is an M-text. */ - MText *mt; - if (c == '"') - mt = mconv_decode_buffer (Mcoding_utf_8, - (unsigned char *) (buf + i), - len - i - 1); - else - { - mt = mtext (); - while ((c = read_number (buf, &i)) >= 0) - mt = mtext_cat_char (mt, c); - } - val = (void *) mt; - } - else if (type == Msymbol) - { - if (! strcmp (buf + i, "nil")) - val = (void *) Mnil; - else - val = (void *) msymbol (buf + i); - } - else if (type == Mplist) - { - val = (void *) mplist__from_string ((unsigned char *) buf + i, - strlen (buf + i)); - } - else - val = NULL; - - if (from == to) - mchartable_set (table, from, val); - else - mchartable_set_range (table, from, to, val); - } - return table; - - label_error: - M17N_OBJECT_UNREF (table); - MERROR (MERROR_DB, NULL); -} - - -/** Load a data of type @c charset from the file FD. */ - -static void * -load_charset (FILE *fp, MSymbol charset_name) -{ - MCharset *charset = MCHARSET (charset_name); - int *decoder; - MCharTable *encoder; - int size; - int i, c; - int found = 0; - MPlist *plist; - - if (! charset) - MERROR (MERROR_DB, NULL); - size = (charset->code_range[15] - - (charset->min_code - charset->code_range_min_code)); - MTABLE_MALLOC (decoder, size, MERROR_DB); - for (i = 0; i < size; i++) - decoder[i] = -1; - encoder = mchartable (Minteger, (void *) MCHAR_INVALID_CODE); - - while ((c = getc (fp)) != EOF) - { - unsigned code1, code2, c1, c2; - int idx1, idx2; - char buf[256]; - - ungetc (c, fp); - fgets (buf, 256, fp); - if (c != '#') - { - if (sscanf (buf, "0x%x-0x%x 0x%x", &code1, &code2, &c1) == 3) - { - idx1 = CODE_POINT_TO_INDEX (charset, code1); - if (idx1 >= size) - continue; - idx2 = CODE_POINT_TO_INDEX (charset, code2); - if (idx2 >= size) - idx2 = size - 1; - c2 = c1 + (idx2 - idx1); - } - else if (sscanf (buf, "0x%x 0x%x", &code1, &c1) == 2) - { - idx1 = idx2 = CODE_POINT_TO_INDEX (charset, code1); - if (idx1 >= size) - continue; - c2 = c1; - } - else - continue; - if (idx1 >= 0 && idx2 >= 0) - { - decoder[idx1] = c1; - mchartable_set (encoder, c1, (void *) code1); - for (idx1++, c1++; idx1 <= idx2; idx1++, c1++) - { - code1 = INDEX_TO_CODE_POINT (charset, idx1); - decoder[idx1] = c1; - mchartable_set (encoder, c1, (void *) code1); - } - found++; - } - } - } - - if (! found) - { - free (decoder); - M17N_OBJECT_UNREF (encoder); - return NULL; - } - plist = mplist (); - mplist_add (plist, Mt, decoder); - mplist_add (plist, Mt, encoder); - return plist; -} - -static char * -gen_database_name (char *buf, MSymbol *tags) -{ - int i; - - strcpy (buf, msymbol_name (tags[0])); - for (i = 1; i < 4; i++) - { - strcat (buf, ", "); - strcat (buf, msymbol_name (tags[i])); - } - return buf; -} - -static void * -load_database (MSymbol *tags, void *extra_info) -{ - FILE *fp; - char *filename = (char *) extra_info; - void *value; - - if (filename[0] == '/') - fp = fopen (filename, "r"); - else - { - MPlist *plist; - char path[PATH_MAX]; - - MPLIST_DO (plist, mdb_dir_list) - { - strcpy (path, (char *) MPLIST_VAL (plist)); - strcat (path, filename); - fp = fopen (path, "r"); - if (fp) - break; - } - } - if (! fp) - MERROR (MERROR_DB, NULL); - - if (tags[0] == Mchar_table) - value = load_chartable (fp, tags[1]); - else if (tags[0] == Mcharset) - value = load_charset (fp, tags[1]); - else - value = mplist__from_file (fp); - fclose (fp); - - if (! value) - MERROR (MERROR_DB, NULL); - return value; -} - - -/** Copy DIRNAME to a newly allocated memory and return it. If - DIRNAME does not end with a slash, append a slash to the new memory. */ - -static char * -duplicate_dirname (char *dirname) -{ - struct stat buf; - int len; - char *str; - - if (! dirname - || stat (dirname, &buf) < 0) - return NULL; - - len = strlen (dirname); - MTABLE_MALLOC (str, len + 2, MERROR_DB); - memcpy (str, dirname, len + 1); - if (str[len - 1] != '/') - { - str[len] = '/'; - str[len + 1] = '\0'; - } - return str; -} - - -/* Internal API */ - -int -mdatabase__init () -{ - char *dir; - int i; - MPlist *plist; - FILE *fp; - - Mchar_table = msymbol ("char-table"); - - mdb_dir_list = mplist (); - /** The macro M17NDIR specifies a directory where the system-wide - MDB_DIR file exists. */ - if ((dir = duplicate_dirname (M17NDIR))) - mplist_set (mdb_dir_list, Mt, dir); - - /* The variable mdatabase_dir specifies a directory where an - application program specific MDB_DIR file exists. */ - if ((dir = duplicate_dirname (mdatabase_dir))) - mplist_push (mdb_dir_list, Mt, dir); - - /* The environment variable M17NDIR (if non-NULL) specifies a - directory where a user specific MDB_DIR file exists. */ - if ((dir = duplicate_dirname (getenv ("M17NDIR")))) - mplist_push (mdb_dir_list, Mt, dir); - - MLIST_INIT1 (&mdb_list, mdbs, 256); - MPLIST_DO (plist, mdb_dir_list) - { - MPlist *pl, *p; - int len; - char path[PATH_MAX]; - - dir = (char *) MPLIST_VAL (plist); - len = strlen (dir); - if (len + MDB_DIR_LEN >= PATH_MAX) - continue; - memcpy (path, dir, len); - memcpy (path + len, MDB_DIR, MDB_DIR_LEN); - if (! (fp = fopen (path, "r"))) - continue; - pl = mplist__from_file (fp); - fclose (fp); - if (! pl) - continue; - MPLIST_DO (p, pl) - { - MDatabase mdb; - MPlist *p1; - int nbytes; - - if (! MPLIST_PLIST_P (p)) - continue; - for (i = 0, p1 = MPLIST_PLIST (p); - i < 4 && MPLIST_KEY (p1) == Msymbol; - i++, p1 = MPLIST_NEXT (p1)) - mdb.tag[i] = MPLIST_SYMBOL (p1); - if (i == 0 - || ! MPLIST_MTEXT_P (p1)) - continue; - for (; i < 4; i++) - mdb.tag[i] = Mnil; - if (mdatabase_find (mdb.tag[0], mdb.tag[1], - mdb.tag[2], mdb.tag[3])) - continue; - - mdb.loader = load_database; - nbytes = mconv_encode_buffer (Mcoding_utf_8, MPLIST_MTEXT (p1), - (unsigned char *) path, PATH_MAX); - if (nbytes < 0 || nbytes >= PATH_MAX) - continue; - path[nbytes++] = '\0'; - mdb.extra_info = (void *) strdup (path); - MLIST_APPEND1 (&mdb_list, mdbs, mdb, MERROR_DB); - } - M17N_OBJECT_UNREF (pl); - } - - mdatabase__finder = ((void *(*) (MSymbol, MSymbol, MSymbol, MSymbol)) - mdatabase_find); - mdatabase__loader = (void *(*) (void *)) mdatabase_load; - - return 0; -} - -void -mdatabase__fini (void) -{ - int i; - MPlist *plist; - - MPLIST_DO (plist, mdb_dir_list) - free (MPLIST_VAL (plist)); - M17N_OBJECT_UNREF (mdb_dir_list); - - for (i = 0; i < mdb_list.used; i++) - { - MDatabase *mdb = mdb_list.mdbs + i; - - if (mdb->loader == load_database) - free (mdb->extra_info); - } - MLIST_FREE1 (&mdb_list, mdbs); -} - -/*** @} */ -#endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */ - - -/* External API */ - -/*** @addtogroup m17nDatabase */ -/*** @{ */ - -/*=*/ -/***en - @brief Directory for application specific data. - - If an application program wants to provide a data specific to the - program or a data overriding what supplied by the m17n database, - it must set this variable to a name of directory that contains the - data files before it calls the macro M17N_INIT (). The directory - may contain a file "mdb.dir" which contains a list of data - definitions in the format described in @ref mdbDir "mdbDir(5)". - - The default value is NULL. */ - -char *mdatabase_dir; - -/*=*/ -/***en - @brief Look for a data in the database. - - The mdatabase_find () function searches the m17n database for a - data who has tags $TAG1 through $TAG4, and returns a pointer to - the data. If such a database is not found, it returns @c - NULL. */ - -/***ja - @brief ¥Ç¡¼¥¿¥Ù¡¼¥¹¤òõ¤¹ - - ´Ø¿ô mdatabase_find () ¤Ï¡¢ m17n ¸À¸ì¾ðÊó¥Ù¡¼¥¹Ãæ¤Ç $TAG1 ¤«¤é - $TAG4 ¤Þ¤Ç¤Î¥¿¥°¤ò»ý¤Ä¥Ç¡¼¥¿¥Ù¡¼¥¹¤òõ¤·¡¢¤½¤ì¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£ - ¤½¤Î¤è¤¦¤Ê¥Ç¡¼¥¿¥Ù¡¼¥¹¤¬¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£ - - @latexonly \IPAlabel{mdatabase_find} @endlatexonly */ - -MDatabase * -mdatabase_find (MSymbol tag0, MSymbol tag1, MSymbol tag2, MSymbol tag3) -{ - int i; - - for (i = 0; i < mdb_list.used; i++) - { - MDatabase *mdb = mdb_list.mdbs + i; - - if (tag0 == mdb->tag[0] - && tag1 == mdb->tag[1] - && tag2 == mdb->tag[2] - && tag3 == mdb->tag[3]) - return mdb; - } - return NULL; -} - -/*=*/ -/***en - @brief Return a data list of the m17n database. - - The mdatabase_list () function searches the m17n database for data - who have tags $TAG1 through $TAG4, and returns their list by a - plist. The value #Mnil in $TAGn means a wild card that matches - any tag. Each element of the plist has key #Mt and value a - pointer to type #MDatabase. */ - -MPlist * -mdatabase_list (MSymbol tag0, MSymbol tag1, MSymbol tag2, MSymbol tag3) -{ - int i; - MPlist *plist = NULL, *pl; - - for (i = 0; i < mdb_list.used; i++) - { - MDatabase *mdb = mdb_list.mdbs + i; - - if ((tag0 == Mnil || tag0 == mdb->tag[0]) - && (tag1 == Mnil || tag1 == mdb->tag[1]) - && (tag2 == Mnil || tag2 == mdb->tag[2]) - && (tag3 == Mnil || tag3 == mdb->tag[3])) - { - if (! plist) - plist = pl = mplist (); - pl = mplist_add (pl, Mt, mdb); - } - } - return plist; -} - - - -/*=*/ -/***en - @brief Define a data of the m17n database. - - The mdatabase_define () function defines a data that has tags - $TAG1 through $TAG4 and additional information $EXTRA_INFO. - - $LOADER is a pointer to a function that loads the data from the - database. This function is called from the mdatabase_load () - function with the two arguments $TAGS and $EXTRA_INFO. Here, - $TAGS is the array of $TAG1 through $TAG4. - - If $LOADER is @c NULL, the default loader of the m17n library is - used. In this case, $EXTRA_INFO must be a string specifying a - filename that contains the data. - - @return - If the operation was successful, mdatabase_define () returns a - pointer to the defined data, which can be used as an argument to - mdatabase_load (). Otherwise, it returns @c NULL. */ - -/***ja - @brief ¥Ç¡¼¥¿¥Ù¡¼¥¹¤òÄêµÁ¤¹¤ë - - ´Ø¿ô mdatabase_define () ¤Ï $TAG1 ¤«¤é $TAG4 ¤Þ¤Ç¤Î¥¿¥°¤ª¤è¤ÓÉղà - ¾ðÊó $EXTRA_INFO ¤ò»ý¤Ä¥Ç¡¼¥¿¥Ù¡¼¥¹¤òÄêµÁ¤¹¤ë¡£ - - $LOADER ¤Ï¤½¤Î¥Ç¡¼¥¿¥Ù¡¼¥¹¤Î¥í¡¼¥É¤ËÍѤ¤¤é¤ì¤ë´Ø¿ô¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢ - ¤ë¡£¤³¤Î´Ø¿ô¤Ï mdatabase_load () ¤«¤é $MDB ¤È $EXTRA_INFO ¤È¤¤¤¦2 - ¤Ä¤Î°ú¿ôÉÕ¤­¤Ç¸Æ¤Ó½Ð¤µ¤ì¤ë¡£¤³¤³¤Ç $MDB ¤Ï mdatabase_load () ¤ËÅÏ - ¤µ¤ì¤¿°ú¿ô¤Ç¤¢¤ë¡£ - - ¤â¤· $LOADER ¤¬ @c NULL ¤Ê¤é¡¢m17n ¥é¥¤¥Ö¥é¥êɸ½à¤Î¥í¡¼¥À¤¬»È¤ï¤ì - ¤ë¡£¤³¤Î¥í¡¼¥À¤Ï¥Ç¡¼¥¿¥Ù¡¼¥¹¤ò $EXTRA_INFO ¤Ë»ØÄꤵ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡ - ¥¤¥ë¤«¤é¥í¡¼¥É¤¹¤ë¡£ - - @return - ½èÍý¤ËÀ®¸ù¤¹¤ì¤Ð mdatabase_define () ¤ÏÄêµÁ¤µ¤ì¤¿¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ø¤Î - ¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£ - - @latexonly \IPAlabel{mdatabase_define} @endlatexonly */ - -/*** - @seealso - mdatabase_load (), mdatabase_define () */ - -MDatabase * -mdatabase_define (MSymbol tag0, MSymbol tag1, MSymbol tag2, MSymbol tag3, - void *(*loader) (MSymbol *, void *), - void *extra_info) -{ - MDatabase *mdb; - - mdb = mdatabase_find (tag0, tag1, tag2, tag3); - if (! mdb) - { - MDatabase template; - - template.tag[0] = tag0, template.tag[1] = tag1; - template.tag[2] = tag2, template.tag[3] = tag3; - MLIST_APPEND1 (&mdb_list, mdbs, template, MERROR_DB); - mdb = mdb_list.mdbs + (mdb_list.used - 1); - } - mdb->loader = loader ? loader : load_database; - mdb->extra_info = extra_info; - if (mdb->loader == load_database) - mdb->extra_info = strdup ((char *) extra_info); - return (&(mdb_list.mdbs[mdb_list.used - 1])); -} - -/*=*/ -/***en - @brief Load a data from the database. - - The mdatabase_load () function loads a data specified in $MDB and - returns the contents. The type of contents depends on the type of - the data. - - If the data is of the @e plist type, this function returns a - pointer to @e plist. - - If the database is of the @e chartable type, it returns a - chartable. The default value of the chartable is set according to - the second tag of the database as below: - -
    - -
  • If the tag is #Msymbol, the default value is #Mnil. -
  • If the tag is #Minteger, the default value is -1. -
  • Otherwise, the default value is @c NULL. - -
- - If the data is of the charset type, it returns a plist of length 2 - (keys are both #Mt). The value of the first element is an array - of integers that maps code points to the corresponding character - codes. The value of the second element is a chartable of integers - that does the reverse mapping. The charset must be defined in - advance. */ - - -/***ja - @brief ¥Ç¡¼¥¿¥Ù¡¼¥¹¤ò¥í¡¼¥É¤¹¤ë - - ´Ø¿ô mdatabase_load () ¤Ï $MDB ¤¬»Ø¤¹¥Ç¡¼¥¿¥Ù¡¼¥¹¤ò¥í¡¼¥É¤·¡¢¤½¤Î - Ãæ¿È¤òÊÖ¤¹¡£ÊÖ¤µ¤ì¤ë¤â¤Î¤Ï¥Ç¡¼¥¿¥Ù¡¼¥¹¤Î¥¿¥¤¥×¤Ë¤è¤Ã¤Æ°Û¤Ê¤ë¡£ - - ¥Ç¡¼¥¿¥Ù¡¼¥¹¤¬ plist ¥¿¥¤¥×¤Ê¤é¤Ð¡¢ @e plist ¤òÊÖ¤¹¡£ - - ¥Ç¡¼¥¿¥Ù¡¼¥¹¤¬ chartable ¥¿¥¤¥×¤Ê¤é¤Ðʸ»ú¥Æ¡¼¥Ö¥ë¤òÊÖ¤¹¡£Ê¸»ú - ¥Æ¡¼¥Ö¥ë¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤϡ¢Âè2¥¿¥°¤Ë¤è¤Ã¤Æ°Ê²¼¤Î¤è¤¦¤Ë·è¤Þ¤ë¡£ - - @li ¥¿¥°¤¬ #Msymbol ¤Ê¤é¡¢¥Ç¥Õ¥©¥ë¥ÈÃÍ¤Ï #Mnil - @li ¥¿¥°¤¬ #Minteger ¤Ê¤é¡¢¥Ç¥Õ¥©¥ë¥ÈÃÍ¤Ï -1 - @li ¤½¤ì°Ê³°¤Ê¤é¡¢¥Ç¥Õ¥©¥ë¥ÈÃÍ¤Ï @c NULL - - ¥Ç¡¼¥¿¥Ù¡¼¥¹¤¬ charset ¥¿¥¤¥×¤Ê¤é¤ÐŤµ 2 ¤Î @c plist ¤òÊÖ¤¹¡Ê¥­¡¼ - ¤Ï¶¦¤Ë #Mt ¡Ë¡£ºÇ½é¤ÎÍ×ÁǤÎÃͤϥ³¡¼¥É¥Ý¥¤¥ó¥È¤òʸ»ú¥³¡¼¥É¤Ë¥Þ¥Ã - ¥×¤¹¤ëÀ°¿ô¤ÎÇÛÎó¤Ç¤¢¤ë¡££²ÈÖÌܤÎÍ×ÁǤÎÃͤϤ½¤ÎµÕ¤Î¥Þ¥Ã¥×¤ò¤¹¤ëʸ»ú - ¥Æ¡¼¥Ö¥ë¤Ç¤¢¤ë¡£¤³¤Îʸ»ú¥»¥Ã¥È¤Ïͽ¤áÄêµÁ¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ - - @latexonly \IPAlabel{mdatabase_load} @endlatexonly - */ - -/*** - @seealso - mdatabase_load (), mdatabase_define () */ - -void * -mdatabase_load (MDatabase *mdb) -{ - int mdebug_mask = MDEBUG_DATABASE; - char buf[256]; - - MDEBUG_PRINT1 (" [DATABASE] loading <%s>.\n", - gen_database_name (buf, mdb->tag)); - return (*mdb->loader) (mdb->tag, mdb->extra_info); -} - -/*=*/ -/***en - @brief Get tags of a data. - - The mdatabase_tag () function returns an array of tags (symbols) - that identify the data in $MDB. The length of the array is - four. */ - -/***ja - @brief ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Î¥¿¥°¤òÆÀ¤ë - - ´Ø¿ô mdatabase_tag () ¤Ï¡¢¥Ç¡¼¥¿¥Ù¡¼¥¹ $MDB ¤Î¥¿¥°¡Ê¥·¥ó¥Ü¥ë¡Ë¤ÎÇÛ - Îó¤òÊÖ¤¹¡£ÇÛÎó¤ÎŤµ¤Ï 4 ¤Ç¤¢¤ë¡£ - - @latexonly \IPAlabel{mdatabase_tag} @endlatexonly */ - -MSymbol * -mdatabase_tag (MDatabase *mdb) -{ - return mdb->tag; -} - -/*** @} */ - -/* - Local Variables: - coding: euc-japan - End: -*/ diff --git a/src/database.h b/src/database.h deleted file mode 100644 index a6d948d..0000000 --- a/src/database.h +++ /dev/null @@ -1,30 +0,0 @@ -/* database.h -- header file for the database module. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -#ifndef _M17N_DATABASE_H_ -#define _M17N_DATABASE_H_ - -#ifndef M17NDIR -#define M17NDIR "/usr/local/share/m17n" -#endif - -#endif /* not _M17N_DATABASE_H_ */ diff --git a/src/draw.c b/src/draw.c deleted file mode 100644 index 28b4981..0000000 --- a/src/draw.c +++ /dev/null @@ -1,2635 +0,0 @@ -/* draw.c -- drawing module. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -/***en - @addtogroup m17nDraw - @brief Drawing M-text on a window. - - The m17n GUI API provides functions to draw M-texts. - - The fonts used for drawing are selected automatically based on the - fontset and the properties of a face. A face also specifies the - appearance of M-texts, i.e. font size, color, underline, etc. - - The drawing format of M-texts can be controlled in a variety of - ways, which provides powerful 2-dimensional layouting - facility. */ - -/***ja - @addtogroup m17nDraw - @brief M-text ɽ¼¨¤Î¤¿¤á¤Î m17n-gui API - - m17n-gui API ¤Ë¤Ï¡¢M-text ¤òɽ¼¨¤¹¤ë¤¿¤á¤Î´Ø¿ô¤¬ÍÑ°Õ¤µ¤ì¤Æ¤¤¤ë¡£É½ - ¼¨¤ËÍѤ¤¤é¤ì¤ë¥Õ¥©¥ó¥È¤Ï¡¢¥Õ¥ì¡¼¥à¤Î¥Õ¥©¥ó¥È¥»¥Ã¥È¤È¥×¥í¥Ñ¥Æ¥£¤Ë´ð - ¤Å¤¤¤Æ¼«Æ°Åª¤Ë·èÄꤵ¤ì¤ë¡£¤Þ¤¿¡¢¿§¤ä²¼Àþ¤Ê¤É¤Î°À­¤â¥Õ¥ì¡¼¥à¤Ë¤è¤Ã - ¤Æ·èÄꤵ¤ì¤ë¡£ */ - -/*=*/ - -#if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE) -/*** @addtogroup m17nInternal - @{ */ - -#include -#include -#include -#include -#include - -#include "config.h" -#include "m17n-gui.h" -#include "m17n-misc.h" -#include "internal.h" -#include "symbol.h" -#include "textprop.h" -#include "internal-gui.h" -#include "face.h" -#include "font.h" - -#ifdef HAVE_FRIBIDI -#include -#endif /* HAVE_FRIBIDI */ - -#define MAX(x, y) ((x) > (y) ? (x) : (y)) -#define MIN(x, y) ((x) < (y) ? (x) : (y)) - -static MSymbol M_glyph_string; - -/* Special scripts */ -static MSymbol Mlatin, Minherited; -/* Special categories */ -static MSymbol McatCc, McatCf; - - -/* Glyph-string composer. */ - -static MSymbol MbidiR; -static MSymbol MbidiAL; -static MSymbol MbidiRLE; -static MSymbol MbidiRLO; -static MSymbol MbidiBN; -static MSymbol MbidiS; - -static void -visual_order (MGlyphString *gstring) -{ - int len = gstring->used - 2; - MGlyph *glyphs; - int *idx = alloca (sizeof (int) * len); - int gidx; - int bidi_sensitive = gstring->control.orientation_reversed; - int size = 0; - MGlyph *g = MGLYPH (1); - int i; -#ifdef HAVE_FRIBIDI - FriBidiCharType base = (gstring->control.orientation_reversed - ? FRIBIDI_TYPE_RTL : FRIBIDI_TYPE_LTR); - FriBidiChar *logical = alloca (sizeof (FriBidiChar) * len); - FriBidiChar *visual; - FriBidiStrIndex *indices; - FriBidiLevel *levels = alloca (sizeof (FriBidiLevel) * len); -#else /* not HAVE_FRIBIDI */ - int *logical = alloca (sizeof (int) * len); - int *indices; - char *levels = alloca (len); -#endif /* not HAVE_FRIBIDI */ - - while (g->type != GLYPH_ANCHOR) - { - MSymbol bidi = (MSymbol) mchar_get_prop (g->c, Mbidi_category); - - if (bidi == MbidiR || bidi == MbidiAL - || bidi == MbidiRLE || bidi == MbidiRLO) - { - bidi_sensitive = 1; - levels[size] = 1; - } - else - levels[size] = 0; - idx[size] = GLYPH_INDEX (g); - logical[size++] = g++->c; - while (g->type != GLYPH_ANCHOR - && (g[-1].pos == g->pos || g->combining_code)) - g++; - } - - if (! bidi_sensitive) - return; - - glyphs = alloca (sizeof (MGlyph) * gstring->used); - memcpy (glyphs, gstring->glyphs, (sizeof (MGlyph) * gstring->used)); -#ifdef HAVE_FRIBIDI - visual = alloca (sizeof (FriBidiChar) * size); - indices = alloca (sizeof (FriBidiStrIndex) * size); - - fribidi_log2vis (logical, size, &base, visual, NULL, indices, levels); -#else /* not HAVE_FRIBIDI */ - indices = alloca (sizeof (int) * size); - for (i = 0; i < size; i++) - { - if (levels[i]) - { - int j, k; - - for (j = i + 1; j < size && levels[j]; j++); - for (k = j--; i < k; i++, j--) - indices[i] = j; - i--; - } - else - indices[i] = i; - } -#endif /* not HAVE_FRIBIDI */ - - /* IDX are indices to gstring->glyphs[]. The glyphs for LOGICAL[N] - starts from gstring->glyphs[IDX[N]]. - - INDICES are indices to LOGICAL[]. The glyph for VISUAL[N] is - originally at LOGICAL[INDICES[N]]. */ - - for (i = 0, gidx = 1; i < size; i++) - { - int j = indices[i]; - int k = idx[j]; - int pos = glyphs[k].pos; - - glyphs[k].bidi_level = levels[j]; -#ifdef HAVE_FRIBIDI - if (visual[i] != logical[j]) - { - /* Mirrored. */ - glyphs[k].c = visual[i]; - if (glyphs[k].rface->rfont) - glyphs[k].code = mfont__encode_char (glyphs[k].rface->rfont, - glyphs[k].c); - } -#endif /* not HAVE_FRIBIDI */ - *(MGLYPH (gidx)) = glyphs[k]; - for (gidx++, k++; - (k < gstring->used - 1 - && (glyphs[k].pos == pos || glyphs[k].combining_code)); - gidx++, k++) - { - glyphs[k].bidi_level = levels[j]; - *(MGLYPH (gidx)) = glyphs[k]; - } - } -} - -static void -reorder_combining_chars (MGlyphString *gstring, int from, int to) -{ - MGlyph *g, *gbeg = MGLYPH (from + 1), *gend = MGLYPH (to), temp; - int reordered = 1; - - while (reordered) - { - reordered = 0; - for (g = gbeg; g != gend; g++) - if (COMBINING_CODE_CLASS (g->combining_code) > 0 - && (COMBINING_CODE_CLASS (g[-1].combining_code) - > COMBINING_CODE_CLASS (g->combining_code))) - { - reordered = 1; - temp = *g; - *g = g[-1]; - g[-1] = temp; - } - } -} - - -/** Scan M-text MT from FROM to TO, and compose glyphs in GSTRING for - displaying them on FRAME. - - This function fills members , , , , , - of glyphs. The other members are filled by - layout_glyph_string. */ - -static void -compose_glyph_string (MFrame *frame, MText *mt, int from, int to, - MGlyphString *gstring) -{ - MRealizedFace *default_rface = frame->rface; - int stop, face_change, language_change, charset_change; - MGlyph g_tmp, *g; - int pos; - MSymbol language = Mnil, script = Mnil, charset = Mnil; - MRealizedFace *rface = default_rface; - int non_ascii_found; - int size = gstring->control.fixed_width; - int ignore_formatting_char = gstring->control.ignore_formatting_char; - int i, limit; - - MLIST_RESET (gstring); - gstring->from = from; - - /* At first generate glyphs while using the member as a - flag for rface re-checking. */ - INIT_GLYPH (g_tmp); - - /** Put anchor glyphs at the head and tail. */ - g_tmp.type = GLYPH_ANCHOR; - g_tmp.pos = g_tmp.to = from; - g_tmp.c = 0; - APPEND_GLYPH (gstring, g_tmp); - - stop = face_change = charset_change = language_change = pos = from; - g = gstring->glyphs + gstring->used; - non_ascii_found = 0; - while (1) - { - int c; - MSymbol this_script; - - if (pos < mtext_nchars (mt)) - c = mtext_ref_char (mt, pos); - else - c = '\n'; - g_tmp.category = Mnil; - if (c < 0x100) - { - if (c == ' ' || c == '\n' || c == '\t') - g_tmp.type = GLYPH_SPACE, this_script = Mnil; - else - g_tmp.type = GLYPH_CHAR, this_script = Mlatin; - } - else - { - g_tmp.category = mchar_get_prop (c, Mcategory); - if (ignore_formatting_char && g_tmp.category == McatCf) - g_tmp.type = GLYPH_SPACE, this_script = Mnil; - else - { - g_tmp.type = GLYPH_CHAR; - this_script = (MSymbol) mchar_get_prop (c, Mscript); - if (this_script == Minherited) - this_script = script; - } - } - - if (pos == stop || script != this_script || g->type != g_tmp.type) - { - if (non_ascii_found && g->type == GLYPH_CHAR) - while (g < gstring->glyphs + gstring->used) - g = mface__for_chars (script, language, charset, - g, gstring->glyphs + gstring->used, size); - g = gstring->glyphs + gstring->used; - non_ascii_found = 0; - script = this_script; - if (pos == to) - break; - if (pos < mtext_nchars (mt) && pos == language_change) - { - language = (MSymbol) mtext_get_prop (mt, pos, Mlanguage); - mtext_prop_range (mt, Mlanguage, pos, NULL, &language_change, 0); - } - if (pos < mtext_nchars (mt) && pos == charset_change) - { - charset = (MSymbol) mtext_get_prop (mt, pos, Mcharset); - mtext_prop_range (mt, Mcharset, pos, NULL, &charset_change, 0); - } - if (pos < mtext_nchars (mt) && pos == face_change) - { - MFace *faces[64]; - int num = mtext_get_prop_values (mt, pos, Mface, - (void **) faces, 64); - - mtext_prop_range (mt, Mface, pos, NULL, &face_change, 1); - rface = (num > 0 - ? mface__realize (frame, faces, num, - language, charset, size) - : default_rface); - } - stop = language_change; - if (stop > charset_change) - stop = charset_change; - if (face_change < stop) - stop = face_change; - } - - g_tmp.c = g_tmp.code = c; - g_tmp.pos = pos++; - g_tmp.to = pos; - g_tmp.rface = rface; - - if (c >= 0x100) - non_ascii_found = 1; - else if (g_tmp.type == GLYPH_CHAR && (c <= 32 || c == 127)) - { - g_tmp.c = '^'; - APPEND_GLYPH (gstring, g_tmp); - if (c < ' ') - g_tmp.c += 0x40; - else - g_tmp.c = '?'; - } - APPEND_GLYPH (gstring, g_tmp); - if (c == '\n' - && gstring->control.two_dimensional) - break; - } - - limit = pos - from; - - /* Append an anchor glyph. */ - g_tmp.type = GLYPH_ANCHOR; - g_tmp.c = 0; - g_tmp.code = MCHAR_INVALID_CODE; - g_tmp.pos = g_tmp.to = pos; - g_tmp.rface = NULL; - APPEND_GLYPH (gstring, g_tmp); - - gstring->to = pos; - - /* Next, run FLT if necessary. */ - for (i = 1, g = MGLYPH (i); g->type != GLYPH_ANCHOR;) - { - MGlyph *this = g; - - if (this->type == GLYPH_CHAR && this->rface->rfont) - { - int start = i++; - MGlyph *tmp = gstring->glyphs + i; - - if (this->rface->rfont->layouter != Mnil) - { - while ((tmp->type == GLYPH_CHAR || tmp->type == GLYPH_SPACE) - && tmp->rface->rfont == this->rface->rfont - && tmp->code != MCHAR_INVALID_CODE) - i++, tmp++; - i = mfont__flt_run (gstring, start, i, - this->rface->rfont->layouter, - this->rface->ascii_rface); - } - else - { - while (this->type == GLYPH_CHAR - && this->c >= 0x100 - && this->category - && MSYMBOL_NAME (this->category)[0] == 'M' - && this->rface->rfont - && this->rface->rfont->layouter == Mnil) - { - int class = (int) mchar_get_prop (this->c, - Mcombining_class); - this->combining_code - = MAKE_COMBINING_CODE_BY_CLASS (class); - i++, this++; - } - if (start + 1 < i) - reorder_combining_chars (gstring, start, i); - } - g = MGLYPH (i); - } - else - i++, g++; - } - - /* At last, reorder glyphs visually if necessary. */ - if (gstring->control.enable_bidi) - visual_order (gstring); -} - - -static int -combining_code_from_class (int class) -{ - int code; - - if (class < 200) - code = MAKE_COMBINING_CODE (3, 1, 3, 1, 128, 128); - else if (class == 200) /* below left attached */ - code = MAKE_COMBINING_CODE (2, 0, 0, 1, 128, 128); - else if (class == 202) /* below attached*/ - code = MAKE_COMBINING_CODE (2, 1, 0, 1, 128, 128); - else if (class == 204) /* below right attached */ - code = MAKE_COMBINING_CODE (2, 2, 0, 1, 128, 128); - else if (class == 208) /* left attached */ - code = MAKE_COMBINING_CODE (3, 0, 3, 2, 128, 128); - else if (class == 210) /* right attached */ - code = MAKE_COMBINING_CODE (3, 2, 3, 0, 128, 128); - else if (class == 212) /* above left attached */ - code = MAKE_COMBINING_CODE (0, 0, 2, 1, 128, 128); - else if (class == 214) /* above attached */ - code = MAKE_COMBINING_CODE (0, 1, 2, 1, 128, 128); - else if (class == 216) /* above right attached */ - code = MAKE_COMBINING_CODE (0, 2, 2, 1, 128, 128); - else if (class == 218) /* below left */ - code = MAKE_COMBINING_CODE (2, 0, 0, 1, 122, 128); - else if (class == 220) /* below */ - code = MAKE_COMBINING_CODE (2, 1, 0, 1, 122, 128); - else if (class == 222) /* below right */ - code = MAKE_COMBINING_CODE (2, 2, 0, 1, 122, 128); - else if (class == 224) /* left */ - code = MAKE_COMBINING_CODE (3, 0, 3, 2, 128, 122); - else if (class == 226) /* right */ - code = MAKE_COMBINING_CODE (3, 2, 3, 0, 128, 133); - else if (class == 228) /* above left */ - code = MAKE_COMBINING_CODE (0, 0, 2, 1, 133, 128); - else if (class == 230) /* above */ - code = MAKE_COMBINING_CODE (0, 1, 2, 1, 133, 128); - else if (class == 232) /* above right */ - code = MAKE_COMBINING_CODE (0, 2, 2, 1, 133, 128); - else if (class == 233) /* double below */ - code = MAKE_COMBINING_CODE (2, 2, 0, 2, 122, 128); - else if (class == 234) /* double above */ - code = MAKE_COMBINING_CODE (0, 2, 2, 2, 133, 128); - else if (class == 240) /* iota subscript */ - code = MAKE_COMBINING_CODE (2, 1, 0, 1, 122, 128); - else /* unknown */ - code = MAKE_COMBINING_CODE (3, 1, 3, 1, 128, 128); - return code; -} - - -static void -layout_glyphs (MFrame *frame, MGlyphString *gstring, int from, int to) -{ - int g_physical_ascent, g_physical_descent; - int g_width, g_lbearing, g_rbearing; - MGlyph *g = MGLYPH (from); - MGlyph *last_g = MGLYPH (to); - - g_physical_ascent = gstring->physical_ascent; - g_physical_descent = gstring->physical_descent; - g_width = g_lbearing = g_rbearing = 0; - - while (g < last_g) - { - MGlyph *base = g++; - MRealizedFont *rfont = base->rface->rfont; - int size = rfont->font.property[MFONT_SIZE]; - int width, lbearing, rbearing; - - mfont__get_metric (rfont, base); - if (g == last_g || ! g->combining_code) - { - /* No combining. */ - if (base->left_padding && base->lbearing < 0) - { - base->xoff = - base->lbearing; - base->width += base->xoff; - base->rbearing += base->xoff; - base->lbearing = 0; - } - if (base->right_padding && base->rbearing > base->width) - { - base->width = base->rbearing; - } - lbearing = (base->lbearing < 0 ? base->lbearing : 0); - rbearing = base->rbearing; - } - else - { - /* With combining glyphs. */ - int left = -base->width; - int right = 0; - int top = - base->ascent; - int bottom = base->descent; - int height = bottom - top; - int begin = base->pos; - int end = base->to; - int i; - - width = base->width; - lbearing = (base->lbearing < 0 ? base->lbearing : 0); - rbearing = base->rbearing; - - while (g != last_g && g->combining_code) - { - int combining_code, base_x, base_y, add_x, add_y, off_x, off_y; - - combining_code = g->combining_code; - if (COMBINING_BY_CLASS_P (combining_code)) - g->combining_code = combining_code - = combining_code_from_class (COMBINING_CODE_CLASS - (combining_code)); - - rfont = g->rface->rfont; - size = rfont->font.property[MFONT_SIZE]; - off_x = (size * (COMBINING_CODE_OFF_X (combining_code) - 128) - / 1000); - off_y = (size * (COMBINING_CODE_OFF_Y (combining_code) - 128) - / 1000); - base_x = COMBINING_CODE_BASE_X (combining_code); - base_y = COMBINING_CODE_BASE_Y (combining_code); - add_x = COMBINING_CODE_ADD_X (combining_code); - add_y = COMBINING_CODE_ADD_Y (combining_code); - - if (begin > g->pos) - begin = g->pos; - else if (end < g->to) - end = g->to; - - mfont__get_metric (rfont, g); - g->xoff = left + (width * base_x - g->width * add_x) / 2 + off_x; - if (g->xoff < left) - left = g->xoff; - if (g->xoff + g->width > right) - right = g->xoff + g->width; - width = right - left; - if (g->xoff + g->lbearing < left + lbearing) - lbearing = g->xoff + g->lbearing - left; - if (g->xoff + g->rbearing > left + rbearing) - rbearing = g->xoff + g->rbearing - left; - - if (base_y < 3) - g->yoff = top + height * base_y / 2; - else - g->yoff = 0; - if (add_y < 3) - g->yoff -= (g->ascent + g->descent) * add_y / 2 - g->ascent; - g->yoff -= off_y; - if (g->yoff - g->ascent < top) - top = g->yoff - g->ascent; - if (g->yoff + g->descent > bottom) - bottom = g->yoff + g->descent; - height = bottom - top; - - g->width = 0; - g++; - } - - base->ascent = - top; - base->descent = bottom; - if (left < - base->width) - { - base->xoff = - base->width - left; - base->width += base->xoff; - base->rbearing += base->xoff; - base->lbearing += base->xoff; - } - if (right > 0) - { - base->width += right; - base->rbearing += right; - base->right_padding = 1; - for (i = 1; base + i != g; i++) - base[i].xoff -= right; - } - - for (i = 0; base + i != g; i++) - { - base[i].pos = begin; - base[i].to = end; - } - } - - g_physical_ascent = MAX (g_physical_ascent, base->ascent); - g_physical_descent = MAX (g_physical_descent, base->descent); - g_lbearing = MIN (g_lbearing, g_width + lbearing); - g_rbearing = MAX (g_rbearing, g_width + rbearing); - g_width += base->width; - } - - gstring->physical_ascent = g_physical_ascent; - gstring->physical_descent = g_physical_descent; - gstring->sub_width = g_width; - gstring->sub_lbearing = g_lbearing; - gstring->sub_rbearing = g_rbearing; -} - - -/** Decide the layout of glyphs in GSTRING. Space glyphs are handled - by this function directly. Character glyphs are handled by - layouter functions registered in font drivers. - - This function fill-in all the remaining members of glyphs. */ - -static void -layout_glyph_string (MFrame *frame, MGlyphString *gstring) -{ - /* Default width of TAB. */ - int tab_width = frame->space_width * (gstring->control.tab_width - ? gstring->control.tab_width : 8); - int tab_found = 0; - MGlyph *g; - MGlyph pad; - MDrawControl *control = &(gstring->control); - int width; - MFaceBoxProp *box; - int box_line_height = 0; - - gstring->ascent = gstring->descent = 0; - gstring->physical_ascent = gstring->physical_descent = 0; - gstring->width = gstring->lbearing = gstring->rbearing = 0; - - g = MGLYPH (1); - box = NULL; - while (g->type != GLYPH_ANCHOR) - { - if (box != g->rface->box) - { - int gidx = GLYPH_INDEX (g); - - if (box) - { - /* Insert the right side of the box. That glyph belongs - to the previous grapheme cluster. */ - MGlyph box_glyph = g[-1]; - - box_glyph.type = GLYPH_BOX; - box_glyph.width - = (control->fixed_width - ? frame->space_width - : box->inner_hmargin + box->width + box->outer_hmargin); - box_glyph.lbearing = 0; - box_glyph.rbearing = box_glyph.width; - box_glyph.xoff = 0; - box_glyph.right_padding = 1; - gstring->width += box_glyph.width; - gstring->rbearing += box_glyph.width; - INSERT_GLYPH (gstring, gidx, box_glyph); - gidx++; - g = MGLYPH (gidx); - } - box = g->rface->box; - if (box) - { - /* Insert the left side of the box. That glyph belongs - to the following grapheme cluster. */ - MGlyph box_glyph = *g; - int box_height = (box->width - + box->inner_vmargin + box->outer_vmargin); - - if (box_line_height < box_height) - box_line_height = box_height; - box_glyph.type = GLYPH_BOX; - box_glyph.width - = (control->fixed_width - ? frame->space_width - : box->inner_hmargin + box->width + box->outer_hmargin); - box_glyph.lbearing = 0; - box_glyph.rbearing = box_glyph.width; - box_glyph.xoff = 0; - box_glyph.left_padding = 1; - gstring->width += box_glyph.width; - gstring->rbearing += box_glyph.width; - INSERT_GLYPH (gstring, gidx, box_glyph); - gidx++; - g = MGLYPH (gidx); - } - } - - if (g->type == GLYPH_CHAR) - { - MRealizedFace *rface = g->rface; - MRealizedFont *rfont = rface->rfont; - MGlyph *fromg = g; - int from = GLYPH_INDEX (g); - - for (g++; g->type == GLYPH_CHAR; g++) - if (! rfont != ! g->rface->rfont - || box != g->rface->box - || ((fromg->code == MCHAR_INVALID_CODE) - != (g->code == MCHAR_INVALID_CODE))) - break; - if (rfont && fromg->code != MCHAR_INVALID_CODE) - { - int extra_width; - int to = GLYPH_INDEX (g); - - layout_glyphs (frame, gstring, from, to); - extra_width = - gstring->sub_lbearing; - if (extra_width > 0 - && (GLYPH_INDEX (g) > 1 - || control->align_head)) - { - g = MGLYPH (from); - pad = *g; - pad.type = GLYPH_PAD; - pad.xoff = 0; - pad.lbearing = 0; - pad.width = pad.rbearing = extra_width; - INSERT_GLYPH (gstring, from, pad); - to++; - gstring->sub_lbearing = 0; - gstring->sub_width += extra_width; - gstring->sub_rbearing += extra_width; - - g = MGLYPH (from - 1); - if (g->type == GLYPH_SPACE) - { - /* The pad just inserted is absorbed (maybe - partially) by the previous space while - keeping at least some space width. For the - moment, we use the arbitrary width 2-pixel. - Perhaps, it should be decided by the current - face, or a default value of the current - frame, which is, however, not yet - implemented. */ - if (extra_width + 2 < g->width) - { - g->width -= extra_width; - } - else - { - extra_width -= g->width - 2; - g->width = 2; - } - gstring->width -= extra_width; - gstring->rbearing -= extra_width; - } - } - - extra_width = gstring->sub_rbearing - gstring->sub_width; - if (extra_width > 0) - { - g = MGLYPH (to); - if (g->type == GLYPH_SPACE && box == g->rface->box) - { - g--; - pad = *g; - pad.type = GLYPH_PAD; - pad.xoff = 0; - pad.lbearing = 0; - pad.width = pad.rbearing = extra_width; - INSERT_GLYPH (gstring, to, pad); - to++; - } - else - g[-1].width += extra_width; - gstring->sub_width += extra_width; - } - - if (gstring->lbearing > gstring->width + gstring->sub_lbearing) - gstring->lbearing = gstring->width + gstring->sub_lbearing; - if (gstring->rbearing < gstring->width + gstring->sub_rbearing) - gstring->rbearing = gstring->width + gstring->sub_rbearing; - gstring->width += gstring->sub_width; - if (gstring->ascent < rface->ascent) - gstring->ascent = rface->ascent; - if (gstring->descent < rface->descent) - gstring->descent = rface->descent; - g = MGLYPH (to); - } - else - { - for (; fromg < g; fromg++) - { - if ((fromg->c >= 0x200B && fromg->c <= 0x200F) - || (fromg->c >= 0x202A && fromg->c <= 0x202E)) - fromg->width = fromg->rbearing = 1; - else - fromg->width = fromg->rbearing = rface->space_width; - fromg->xoff = fromg->lbearing = 0; - fromg->ascent = fromg->descent = 0; - gstring->width += fromg->width; - gstring->rbearing += fromg->width; - } - if (gstring->ascent < frame->rface->ascent) - gstring->ascent = frame->rface->ascent; - if (gstring->descent < frame->descent) - gstring->descent = frame->rface->descent; - } - } - else if (g->type == GLYPH_SPACE) - { - if (g->c == ' ') - g->width = g->rface->space_width; - else if (g->c == '\n') - { - g->width = control->cursor_width; - if (g->width) - { - if (control->cursor_bidi) - g->width = 3; - else if (g->width < 0) - g->width = g->rface->space_width; - } - } - else if (g->c == '\t') - { - g->width = tab_width - ((gstring->indent + gstring->width) - % tab_width); - tab_found = 1; - } - else - g->width = 1; - if (g[-1].type == GLYPH_PAD) - { - /* This space glyph absorbs (maybe partially) the - previous padding glyph. */ - g->width -= g[-1].width; - if (g->width < 1) - /* But, keep at least some space width. For the - moment, we use the arbitrary width 2-pixel. */ - g->width = 2; - } - g->rbearing = g->width; - gstring->width += g->width; - gstring->rbearing += g->width; - if (g->rface->rfont) - { - if (gstring->ascent < g->rface->ascent) - gstring->ascent = g->rface->ascent; - if (gstring->descent < g->rface->descent) - gstring->descent = g->rface->descent; - } - g++; - } - else - { - gstring->width += g->width; - gstring->rbearing += g->width; - g++; - } - } - - if (box) - { - /* Insert the right side of the box. */ - int gidx = GLYPH_INDEX (g); - MGlyph box_glyph = g[-1]; - - box_glyph.type = GLYPH_BOX; - box_glyph.width - = (control->fixed_width - ? frame->space_width - : box->inner_hmargin + box->width + box->outer_hmargin); - box_glyph.lbearing = 0; - box_glyph.rbearing = box_glyph.width; - box_glyph.xoff = 0; - box_glyph.right_padding = 1; - gstring->width += box_glyph.width; - gstring->rbearing += box_glyph.width; - INSERT_GLYPH (gstring, gidx, box_glyph); - } - - gstring->text_ascent = gstring->ascent; - gstring->text_descent = gstring->descent; - if (gstring->text_ascent < gstring->physical_ascent) - gstring->text_ascent = gstring->physical_ascent; - if (gstring->text_descent < gstring->physical_descent) - gstring->text_descent = gstring->physical_descent; - gstring->line_ascent = gstring->text_ascent; - gstring->line_descent = gstring->text_descent; - if (box_line_height > 0) - { - gstring->line_ascent += box_line_height; - gstring->physical_ascent = gstring->line_ascent; - gstring->line_descent += box_line_height; - gstring->physical_descent = gstring->line_descent; - } - - if (gstring->line_ascent < control->min_line_ascent) - gstring->line_ascent = control->min_line_ascent; - else if (control->max_line_ascent - && control->max_line_ascent > control->min_line_ascent - && gstring->line_ascent > control->max_line_ascent) - gstring->line_ascent = control->max_line_ascent; - - if (gstring->line_descent < control->min_line_descent) - gstring->line_descent = control->min_line_descent; - else if (control->max_line_descent - && control->max_line_descent > control->min_line_descent - && gstring->line_descent > control->max_line_descent) - gstring->line_descent = control->max_line_descent; - gstring->height = gstring->line_ascent + gstring->line_descent; - - if (control->orientation_reversed - && tab_found) - { - /* We must adjust TAB width for RTL orientation. */ - width = gstring->indent; - - for (g = MGLYPH (gstring->used - 2); g->type != GLYPH_ANCHOR; g--) - { - if (g->type == GLYPH_CHAR && g->c == '\t') - { - int this_width = tab_width - (width % tab_width); - - if (g[1].type == GLYPH_PAD) - this_width -= g[1].width; - if (g[-1].type == GLYPH_PAD) - this_width -= g[-1].width; - if (this_width < 2) - this_width = 2; - gstring->width += this_width - g->width; - gstring->rbearing += this_width - g->width; - g->width = this_width; - width += this_width; - } - else - width += g->width; - } - } -} - - -static MDrawRegion -draw_background (MFrame *frame, MDrawWindow win, int x, int y, - MGlyphString *gstring, int from, int to, - int *from_idx, int *to_idx, int *to_x) -{ - MGlyph *g = MGLYPH (1); - MDrawRegion region = (MDrawRegion) NULL; - MDrawControl *control = &gstring->control; - int cursor_pos = -1; - int prev_pos = -1; - int cursor_bidi = control->cursor_bidi; - - if (control->with_cursor && control->cursor_width) - { - if (gstring->from <= control->cursor_pos - && gstring->to > control->cursor_pos) - cursor_pos = control->cursor_pos; - if (cursor_bidi - && gstring->from <= control->cursor_pos - 1 - && gstring->to > control->cursor_pos - 1) - prev_pos = control->cursor_pos - 1; - } - - *from_idx = *to_idx = 0; - while (g->type != GLYPH_ANCHOR) - { - if (g->pos >= from && g->pos < to) - { - MGlyph *fromg = g, *cursor = NULL; - MRealizedFace *rface = g->rface; - int width = 0; - int cursor_width = 0; - int cursor_x; - - if (! *from_idx) - *from_idx = GLYPH_INDEX (g); - while (g->pos >= from && g->pos < to - && g->rface == rface) - { - g->enabled = 1; - if (g->type != GLYPH_BOX - && g->pos <= cursor_pos && g->to > cursor_pos) - { - if (! cursor) - cursor = g, cursor_x = x + width; - cursor_width += g->width; - } - width += g++->width; - } - if (width > 0 - && (control->as_image - || rface->face.property[MFACE_BACKGROUND] != Mnil - || rface->face.property[MFACE_VIDEOMODE] == Mreverse)) - { - int this_x = x, this_width = width; - - if (fromg->type == GLYPH_BOX) - this_x += fromg->width, this_width -= fromg->width; - if (g[-1].type == GLYPH_BOX) - this_width -= g[-1].width; - mwin__fill_space (frame, win, rface, 0, - this_x, y - gstring->text_ascent, this_width, - gstring->text_ascent + gstring->text_descent, - control->clip_region); - } - if (cursor) - { - MDrawMetric rect; - - rect.x = cursor_x; - rect.y = y - gstring->text_ascent; - rect.height = gstring->text_ascent + gstring->text_descent; - if (! cursor_bidi) - { - rect.width = ((control->cursor_width > 0 - && control->cursor_width < cursor_width) - ? control->cursor_width : cursor_width); - } - else - { - if (cursor->bidi_level % 2) - rect.x += cursor_width - 1; - rect.width = 1; - } - mwin__fill_space (frame, win, rface, 1, - rect.x, rect.y, rect.width, rect.height, - control->clip_region); - if (! region) - region = mwin__region_from_rect (&rect); - else - mwin__region_add_rect (region, &rect); - mwin__verify_region (frame, region); - if (cursor_bidi) - { - if (cursor->bidi_level % 2) - rect.x -= 3; - rect.height = 2; - rect.width = cursor_width < 4 ? cursor_width : 4; - mwin__fill_space (frame, win, rface, 1, - rect.x, rect.y, rect.width, rect.height, - control->clip_region); - mwin__region_add_rect (region, &rect); - mwin__verify_region (frame, region); - } - } - - if (prev_pos >= 0) - { - int temp_width = 0; - - cursor_width = 0; - cursor = NULL; - while (fromg < g) - { - if (fromg->type != GLYPH_BOX - && fromg->pos <= prev_pos && fromg->to > prev_pos) - { - if (! cursor) - cursor = fromg, cursor_x = x + temp_width; - cursor_width += fromg->width; - } - temp_width += fromg++->width; - } - if (cursor) - { - MDrawMetric rect; - - rect.x = cursor_x; - if (! (cursor->bidi_level % 2)) - rect.x += cursor_width - 1; - rect.y = y - gstring->text_ascent; - rect.height = gstring->text_ascent + gstring->text_descent; - rect.width = 1; - mwin__fill_space (frame, win, rface, 1, - rect.x, rect.y, rect.width, rect.height, - control->clip_region); - if (! region) - region = mwin__region_from_rect (&rect); - else - mwin__region_add_rect (region, &rect); - mwin__verify_region (frame, region); - rect.y += rect.height - 2; - rect.height = 2; - rect.width = cursor_width < 4 ? cursor_width : 4; - if (! (cursor->bidi_level % 2)) - rect.x -= rect.width - 1; - mwin__fill_space (frame, win, rface, 1, - rect.x, rect.y, rect.width, rect.height, - control->clip_region); - mwin__region_add_rect (region, &rect); - mwin__verify_region (frame, region); - } - } - x += width; - *to_idx = GLYPH_INDEX (g); - *to_x = x; - } - else - g++->enabled = 0; - } - return region; -} - -static void -render_glyphs (MFrame *frame, MDrawWindow win, int x, int y, int width, - MGlyphString *gstring, int from_idx, int to_idx, - int reverse, MDrawRegion region) -{ - MGlyph *g = MGLYPH (from_idx), *gend = MGLYPH (to_idx); - - if (region) - { - MDrawMetric rect; - - mwin__region_to_rect (region, &rect); - if (rect.x > x) - { - while (g != gend && x + g->rbearing <= rect.x) - { - x += g->width; - width -= g++->width; - while (! g->enabled && g != gend) - g++; - } - } - rect.x += rect.width; - if (rect.x < x + width) - { - while (g != gend && x + width - gend[-1].width >= rect.x) - { - width -= (--gend)->width; - while (! gend->enabled && g != gend) - gend--; - } - if (g != gend) - while (gend[-1].to == gend->to) gend++; - } - } - - while (g != gend) - { - if (g->enabled) - { - MRealizedFace *rface = g->rface; - int width = g->width; - MGlyph *from_g = g++; - - /* Handle the glyphs of the same type/face at once. */ - while (g != gend - && g->type == from_g->type - && g->rface == rface - && (g->code < 0) == (from_g->code < 0) - && g->enabled) - width += g++->width; - - if (from_g->type == GLYPH_CHAR) - { - MFontDriver *driver; - - if (rface->rfont && from_g->code >= 0) - driver = rface->rfont->driver; - else - driver = mfont__driver_list[MFONT_TYPE_WIN]; - (driver->render) (win, x, y, gstring, from_g, g, - reverse, region); - } - else if (from_g->type == GLYPH_BOX) - { - /* Draw the left or right side of a box. If - from_g->lbearing is nonzero, this is the left side, - else this is the right side. */ - mwin__draw_box (frame, win, gstring, from_g, x, y, 0, region); - } - - if (from_g->type != GLYPH_BOX) - { - if (rface->hline) - mwin__draw_hline (frame, win, gstring, rface, reverse, - x, y, width, region); - if (rface->box - && ! reverse) - /* Draw the top and bottom side of a box. */ - mwin__draw_box (frame, win, gstring, from_g, - x, y, width, region); - } - x += width; - } - else - g++; - } -} - - -static int -find_overlapping_glyphs (MGlyphString *gstring, int *left, int *right, - int *from_x, int *to_x) -{ - MGlyph *g; - int left_idx = *left, right_idx = *right; - int left_x, right_x, x; - - for (g = MGLYPH (*left) - 1, x = 0; g->type != GLYPH_ANCHOR; g--) - { - x -= g->width; - if (x + g->rbearing > 0) - { - while (g[-1].pos == g->pos && g[-1].type != GLYPH_ANCHOR) - x -= (--g)->width; - left_idx = GLYPH_INDEX (g); - left_x = x; - } - } - - for (g = MGLYPH (*right), x = 0; g->type != GLYPH_ANCHOR; g++) - { - x += g->width; - if (x - g->width + g->lbearing < 0) - { - while (g->pos == g[1].pos && g[1].type != GLYPH_ANCHOR) - x += (++g)->width; - right_idx = GLYPH_INDEX (g) + 1; - right_x = x; - } - } - - if (*left == left_idx && *right == right_idx) - return 0; - - if (*left != left_idx) - { - for (g = MGLYPH (*left) - 1; GLYPH_INDEX (g) >= left_idx; g--) - g->enabled = 1; - *left = left_idx; - *from_x += left_x; - } - if (*right != right_idx) - { - for (g = MGLYPH (*right); GLYPH_INDEX (g) < right_idx; g++) - g->enabled = 1; - *right = right_idx; - *to_x += right_x; - } - return 1; -} - - -static int -gstring_width (MGlyphString *gstring, int from, int to, int *rbearing) -{ - MGlyph *g; - int width; - - if (from <= gstring->from && to >= gstring->to) - { - if (rbearing) - *rbearing = gstring->rbearing; - return gstring->width; - } - - if (rbearing) - *rbearing = 0; - for (g = MGLYPH (1), width = 0; g->type != GLYPH_ANCHOR; g++) - if (g->pos >= from && g->pos < to) - { - if (rbearing && width + g->rbearing > *rbearing) - *rbearing = width + g->rbearing; - width += g->width; - } - return width; -} - - -static void -render_glyph_string (MFrame *frame, MDrawWindow win, int x, int y, - MGlyphString *gstring, int from, int to) -{ - MDrawControl *control = &gstring->control; - MDrawMetric rect; - MDrawRegion clip_region, cursor_region; - int from_idx, to_idx; - int to_x; - - if (control->orientation_reversed) - x -= gstring->indent + gstring_width (gstring, from, to, NULL); - else - x += gstring->indent; - - /* At first, draw all glyphs without cursor. */ - cursor_region = draw_background (frame, win, x, y, gstring, from, to, - &from_idx, &to_idx, &to_x); - - if (control->partial_update) - { - rect.x = x; - rect.width = to_x - x; - if (find_overlapping_glyphs (gstring, &from_idx, &to_idx, &x, &to_x)) - { - rect.y = y - gstring->line_ascent; - rect.height = gstring->height; - clip_region = mwin__region_from_rect (&rect); - if (control->clip_region) - mwin__intersect_region (clip_region, control->clip_region); - } - else - clip_region = control->clip_region; - } - else - clip_region = control->clip_region; - - render_glyphs (frame, win, x, y, to_x - x, gstring, from_idx, to_idx, - 0, clip_region); - if (cursor_region) - { - if (clip_region) - mwin__intersect_region (cursor_region, clip_region); - render_glyphs (frame, win, x, y, to_x - x, gstring, from_idx, to_idx, - 1, cursor_region); - } - if (clip_region != control->clip_region) - mwin__free_region (clip_region); - if (cursor_region) - mwin__free_region (cursor_region); - return; -} - -static int gstring_num; - -static void -free_gstring (void *object) -{ - MGlyphString *gstring = (MGlyphString *) object; - - if (gstring->next) - free_gstring (gstring->next); - if (gstring->size > 0) - free (gstring->glyphs); - free (gstring); - gstring_num--; -} - - -static MGlyphString scratch_gstring; - -static MGlyphString * -alloc_gstring (MText *mt, int pos, MDrawControl *control, int line, int y) -{ - MGlyphString *gstring; - - if (pos == mt->nchars) - { - gstring = &scratch_gstring; - } - else - { - M17N_OBJECT (gstring, free_gstring, MERROR_DRAW); - MLIST_INIT1 (gstring, glyphs, 128); - gstring_num++; - } - - gstring->top = gstring; - gstring->mt = mt; - gstring->control = *control; - gstring->indent = gstring->width_limit = 0; - if (control->format) - (*control->format) (line, y, &(gstring->indent), &(gstring->width_limit)); - else - gstring->width_limit = control->max_line_width; - return gstring; -} - -/* Truncate the line width of GSTRING to GSTRING->width_limit. */ - -static void -truncate_gstring (MFrame *frame, MText *mt, MGlyphString *gstring) -{ - int width; - int i; - int *pos_width; - MGlyph *g; - int pos; - - /* Setup the array POS_WIDTH so that POS_WIDTH[I - GSTRING->from] is - a width of glyphs for the character at I of GSTRING->mt. If I is - not a beginning of a grapheme cluster, the corresponding element - is 0. */ - MTABLE_ALLOCA (pos_width, gstring->to - gstring->from, MERROR_DRAW); - memset (pos_width, 0, sizeof (int) * (gstring->to - gstring->from)); - for (g = MGLYPH (1); g->type != GLYPH_ANCHOR; g++) - pos_width[g->pos - gstring->from] += g->width; - for (i = 0, width = 0; i < gstring->to - gstring->from; i++) - { - if (pos_width[i] > 0) - { - if (width + pos_width[i] > gstring->width_limit) - break; - } - width += pos_width[i]; - } - - pos = gstring->from + i; - if (gstring->control.line_break) - { - pos = (*gstring->control.line_break) (gstring->mt, gstring->from + i, - gstring->from, gstring->to, 0, 0); - if (pos <= gstring->from || pos >= gstring->to) - return; - } - compose_glyph_string (frame, mt, gstring->from, pos, gstring); - layout_glyph_string (frame, gstring); -} - - -/* Return a gstring that covers a character at POS. */ - -static MGlyphString * -get_gstring (MFrame *frame, MText *mt, int pos, int to, MDrawControl *control) -{ - MGlyphString *gstring = NULL; - - if (pos < mtext_nchars (mt)) - { - MTextProperty *prop = mtext_get_property (mt, pos, M_glyph_string); - - if (prop - && ((prop->start != 0 - && mtext_ref_char (mt, prop->start - 1) != '\n') - || (prop->end < mtext_nchars (mt) - && mtext_ref_char (mt, prop->end - 1) != '\n'))) - { - mtext_detach_property (prop); - prop = NULL; - } - if (prop) - { - gstring = prop->val; - if (memcmp (control, &gstring->control, - (char *) (&control->with_cursor) - - (char *) (control))) - { - mtext_detach_property (prop); - gstring = NULL; - } - } - } - else if (! control->cursor_width) - return NULL; - - if (gstring) - { - MGlyphString *gst; - int offset; - - offset = mtext_character (mt, pos, 0, '\n'); - if (offset < 0) - offset = 0; - else - offset++; - offset -= gstring->from; - if (offset) - for (gst = gstring; gst; gst = gst->next) - { - int i; - - gst->from += offset; - gst->to += offset; - for (i = 0; i < gst->used; i++) - { - gst->glyphs[i].pos += offset; - gst->glyphs[i].to += offset; - } - } - M17N_OBJECT_REF (gstring); - } - else - { - int beg, end; - int line = 0, y = 0; - - if (control->two_dimensional) - { - beg = mtext_character (mt, pos, 0, '\n'); - if (beg < 0) - beg = 0; - else - beg++; - end = mtext_nchars (mt) + (control->cursor_width != 0); - } - else - { - beg = pos; - end = to; - } - gstring = alloc_gstring (mt, beg, control, line, y); - compose_glyph_string (frame, mt, beg, end, gstring); - layout_glyph_string (frame, gstring); - end = gstring->to; - if (control->two_dimensional - && gstring->width_limit - && gstring->width > gstring->width_limit) - { - MGlyphString *gst = gstring; - - truncate_gstring (frame, mt, gst); - while (gst->to < end) - { - line++, y += gst->height; - gst->next = alloc_gstring (mt, gst->from, control, line, y); - gst->next->top = gstring; - compose_glyph_string (frame, mt, gst->to, end, gst->next); - gst = gst->next; - layout_glyph_string (frame, gst); - if (gst->width <= gst->width_limit) - break; - truncate_gstring (frame, mt, gst); - } - } - - if (! control->disable_caching && pos < mtext_nchars (mt)) - { - MTextProperty *prop = mtext_property (M_glyph_string, gstring, - MTEXTPROP_VOLATILE_STRONG); - - if (end > mtext_nchars (mt)) - end = mtext_nchars (mt); - mtext_attach_property (mt, beg, end, prop); - M17N_OBJECT_UNREF (prop); - } - } - - while (gstring->to <= pos) - { - if (! gstring->next) - mdebug_hook (); - gstring = gstring->next; - } - gstring->control = *control; - - return gstring; -} - - -static MDrawControl control_noop; - -#define ASSURE_CONTROL(control) \ - if (! control) \ - control = &control_noop; \ - else - - -static int -draw_text (MFrame *frame, MDrawWindow win, int x, int y, - MText *mt, int from, int to, - MDrawControl *control) -{ - MGlyphString *gstring; - - M_CHECK_POS_X (mt, from, -1); - ASSURE_CONTROL (control); - if (to > mtext_nchars (mt) + (control->cursor_width != 0)) - to = mtext_nchars (mt) + (control->cursor_width != 0); - else if (to < from) - to = from; - - gstring = get_gstring (frame, mt, from, to, control); - if (! gstring) - MERROR (MERROR_DRAW, -1); - render_glyph_string (frame, win, x, y, gstring, from, to); - from = gstring->to; - while (from < to) - { - y += gstring->line_descent; - M17N_OBJECT_UNREF (gstring->top); - gstring = get_gstring (frame, mt, from, to, control); - y += gstring->line_ascent; - render_glyph_string (frame, win, x, y, gstring, from, to); - from = gstring->to; - } - M17N_OBJECT_UNREF (gstring->top); - - return 0; -} - - -static MGlyph * -find_glyph_in_gstring (MGlyphString *gstring, int pos, int forwardp) -{ - MGlyph *g; - - if (forwardp) - { - for (g = MGLYPH (1); g->type != GLYPH_ANCHOR; g++) - if (g->pos <= pos && g->to > pos) - break; - } - else - { - for (g = MGLYPH (gstring->used - 2); g->type != GLYPH_ANCHOR; g--) - if (g->pos <= pos && g->to > pos) - break; - } - return g; -} - - -/* for debugging... */ -char work[16]; - -char * -dump_combining_code (int code) -{ - char *vallign = "tcbB"; - char *hallign = "lcr"; - char *p; - int off_x, off_y; - - if (! code) - return "none"; - if (COMBINING_BY_CLASS_P (code)) - code = combining_code_from_class (COMBINING_CODE_CLASS (code)); - work[0] = vallign[COMBINING_CODE_BASE_Y (code)]; - work[1] = hallign[COMBINING_CODE_BASE_X (code)]; - off_y = COMBINING_CODE_OFF_Y (code) - 128; - off_x = COMBINING_CODE_OFF_X (code) - 128; - if (off_y > 0) - sprintf (work + 2, "+%d", off_y); - else if (off_y < 0) - sprintf (work + 2, "%d", off_y); - else if (off_x == 0) - sprintf (work + 2, "-"); - p = work + strlen (work); - if (off_x > 0) - sprintf (p, ">%d", off_x); - else if (off_x < 0) - sprintf (p, "<%d", -off_x); - p += strlen (p); - p[0] = vallign[COMBINING_CODE_ADD_Y (code)]; - p[1] = hallign[COMBINING_CODE_ADD_X (code)]; - p[2] = '\0'; - return work; -} - -void -dump_gstring (MGlyphString *gstring, int indent) -{ - char *prefix = (char *) alloca (indent + 1); - MGlyph *g, *last_g = gstring->glyphs + gstring->used; - - memset (prefix, 32, indent); - prefix[indent] = 0; - - fprintf (stderr, "(glyph-string"); - - for (g = MGLYPH (0); g < last_g; g++) - fprintf (stderr, - "\n%s (%02d %s pos:%d-%d c:%04X code:%04X face:%x cmb:%s w:%02d bidi:%d)", - prefix, - g - gstring->glyphs, - (g->type == GLYPH_SPACE ? "SPC": g->type == GLYPH_PAD ? "PAD" - : g->type == GLYPH_ANCHOR ? "ANC" - : g->type == GLYPH_BOX ? "BOX" : "CHR"), - g->pos, g->to, g->c, g->code, (unsigned) g->rface, - dump_combining_code (g->combining_code), - g->width, g->bidi_level); - fprintf (stderr, ")"); -} - - -/* m17n-X internal APIs */ - -int -mdraw__init () -{ - M_glyph_string = msymbol_as_managing_key (" glyph-string"); - - memset (&scratch_gstring, 0, sizeof (scratch_gstring)); - MLIST_INIT1 (&scratch_gstring, glyphs, 3); - - Mlatin = msymbol ("latin"); - Minherited = msymbol ("inherited"); - - McatCc = msymbol ("Cc"); - McatCf = msymbol ("Cf"); - - MbidiR = msymbol ("R"); - MbidiAL = msymbol ("AL"); - MbidiRLE = msymbol ("RLE"); - MbidiRLO = msymbol ("RLO"); - MbidiBN = msymbol ("BN"); - MbidiS = msymbol ("S"); -#ifdef HAVE_FRIBIDI - fribidi_set_mirroring (TRUE); -#endif - - return 0; -} - -void -mdraw__fini () -{ - MLIST_FREE1 (&scratch_gstring, glyphs); -} - -/*** @} */ -#endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */ - - -/* External API */ -/*** @addtogroup m17nDraw */ -/*** @{ */ - -/*=*/ -/***en - @brief Draw an M-text on a window. - - The mdraw_text () function draws the text between $FROM and $TO of - M-text $MT on window $WIN of frame $FRAME at coordinate ($X, $Y). - - The appearance of the text (size, style, color, etc) is specified - by the value of the text property whose key is @c Mface. If the - M-text or a part of the M-text does not have such a text property, - the default face of $FRAME is used. - - The font used to draw a character in the M-text is selected from - the value of the fontset property of a face by the following - algorithm: - -
    - -
  1. Search the text properties given to the character for the one - whose key is @c Mcharset; its value should be either a symbol - specifying a charset or Mnil. If the value is Mnil, proceed - to the next step. - - Otherwise, search the mapping table of the fontset for the - charset. If no entry is found proceed to the next step. If - an entry is found, use one of the fonts in the entry that has - a glyph for the character and that matches best with the face - properties. If no such font exists, proceed to the next - step. - -
  2. Get the character-property script of the character. If it is - inherited, get the script property from the previous - characters. If there is no previous character, or none of - them has the script property other than inherited, proceed to - the next step. - - Search the text properties given to the character for the one - whose key is @c Mlanguage; its value should be either a - symbol specifying a language or @c Mnil. - - Search the mapping table of the fontset for the combination - of the script and language. If no entry is found, proceed to - the next step. If an entry is found, use one of the fonts in - the entry that has a glyph for the character and that matches - best with the face properties. If no such font exists, - proceed to the next step. - -
  3. Search the fall-back table of the fontset for a font that has - a glyph of the character. If such a font is found, use that - font. - -
- - If no font is found by the algorithm above, this function draws an - empty box for the character. - - This function draws only the glyph foreground. To specify the - background color, use mdraw_image_text () or - mdraw_text_with_control (). - - This function is the counterpart of XDrawString (), - XmbDrawString (), and XwcDrawString () functions - in the X Window System. - - @return - If the operation was successful, mdraw_text () returns 0. If an - error is detected, it returns -1 and assigns an error code to the - external variable @c merror_code. */ - -/***ja - @brief ¥¦¥£¥ó¥É¥¦¤Ë M-text ¤òɽ¼¨¤¹¤ë - - ´Ø¿ô mdraw_text () ¤Ï¡¢¥Õ¥ì¡¼¥à $FRAME ¤Î¥¦¥£¥ó¥É¥¦ $WIN ¤ÎºÂɸ - ($X, $Y) ¤Ë¡¢M-text $MT ¤Î $FROM ¤«¤é $TO ¤Þ¤Ç¤Î¥Æ¥­¥¹¥È¤ò - ɽ¼¨¤¹¤ë¡£ - - ¥Ý¥¤¥ó¥¿ $RET_DESCENT ¤¬ @c NULL ¤Ç¤Ê¤±¤ì¤Ð¡¢É½¼¨¤·¤¿¥Æ¥­¥¹¥È¤Î¥Ç¥£¥» - ¥ó¥È¤¬¤½¤³¤Ë³ÊǼ¤µ¤ì¤ë¡£ - - ¥Æ¥­¥¹¥È¤Î¸«±É¤¨¡Ê¥Õ¥©¥ó¥È¡¢¥¹¥¿¥¤¥ë¡¢¿§¤Ê¤É¡Ë¤Ï¡¢¥­¡¼¤¬ @c Mface - ¤Ç¤¢¤ë¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ÎÃͤˤè¤Ã¤Æ·è¤Þ¤ë¡£M-text ¤Î°ìÉô¤¢¤ë¤¤¤Ï - Á´Éô¤Ë¤½¤Î¤è¤¦¤Ê¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤¬ÉÕ¤¤¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ë¤Ï¡¢$FRAME - ¤Î¥Ç¥Õ¥©¥ë¥È¥Õ¥§¡¼¥¹¤¬ÍѤ¤¤é¤ì¤ë¡£ - - M-text ¤Î³Æʸ»ú¤òɽ¼¨¤¹¤ë¥Õ¥©¥ó¥È¤Ï¡¢$FACE ¤Î fontset ¥×¥í¥Ñ¥Æ¥£¤Î - Ãͤ«¤é°Ê²¼¤Î¥¢¥ë¥´¥ê¥º¥à¤ÇÁª¤Ð¤ì¤ë¡£ - -
    - -
  1. ¤½¤Îʸ»ú¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥­¡¼¤¬ @c Mlanguage ¤Ç¤¢ - ¤ë¤â¤Î¤ÎÃͤòÄ´¤Ù¤ë¡£¤³¤ÎÃͤϸÀ¸ì¤òɽ¤ï¤¹¥·¥ó¥Ü¥ë¤« @c Mnil ¤Î¤¤ - ¤º¤ì¤«¤Ç¤¢¤ë¡£¼¡¤Ë¥­¡¼¤¬ @c Mscript ¤Ç¤¢¤ë¤â¤Î¤ÎÃͤòÄ´¤Ù¤ë¡£ - ¤³¤ÎÃͤϥ¹¥¯¥ê¥×¥È¤òɽ¤ï¤¹¥·¥ó¥Ü¥ë¤« @c Mnil ¤Î¤É¤Á¤é¤«¤Ç¤¢¤ë¡£ - - ¤É¤Á¤é¤â @c Mnil ¤Ê¤é¤Ð¡¢¼¡¤Î¥¹¥Æ¥Ã¥×¤Ë¿Ê¤à¡£ - - ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤½¤Î¸À¸ì¤È¥¹¥¯¥ê¥×¥È¤ÎÁȤ߹ç¤ï¤»¤ò»È¤Ã - ¤Æ¡¢¤½¤Î¥Õ¥©¥ó¥È¥»¥Ã¥È¤Î¥Þ¥Ã¥Ô¥ó¥°¥Æ¡¼¥Ö¥ë¤ò¤Ò¤¯¡£¥Õ¥©¥ó¥È¤¬ - ¤ß¤Ä¤«¤ê¡¢¤«¤Ä¤½¤Î¥Õ¥©¥ó¥È¤Ç¸½ºß¤Îʸ»ú¤¬É½¼¨¤Ç¤­¤ì¤Ð¡¢¤½¤Î¥Õ¥© - ¥ó¥È¤ò»È¤¦¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¼¡¤Î¥¹¥Æ¥Ã¥×¤Ë¿Ê¤à¡£ - -
  2. ¤½¤Îʸ»ú¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥­¡¼¤¬ @c Mcharset ¤Ç¤¢¤ë - ¤â¤Î¤ÎÃͤòÄ´¤Ù¤ë¡£¤³¤ÎÃͤÏʸ»ú¥»¥Ã¥È¤òɽ¤ï¤¹¥·¥ó¥Ü¥ë¤« @c Mnil - ¤Î¤É¤Á¤é¤«¤Ç¤¢¤ë¡£@c Mnil ¤Ê¤é¤Ð¡¢¼¡¤Î¥¹¥Æ¥Ã¥×¤Ë¿Ê¤à¡£ - - ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¸«¤Ä¤«¤Ã¤¿Ê¸»ú¥»¥Ã¥È»È¤Ã¤Æ¡¢¤½¤Î¥Õ¥©¥ó¥È¥»¥Ã - ¥È¤Î¥Þ¥Ã¥Ô¥ó¥°¥Æ¡¼¥Ö¥ë¤ò¤Ò¤¯¡£¥Õ¥©¥ó¥È¤¬¤ß¤Ä¤«¤ê¡¢¤«¤Ä¤½¤Î¥Õ¥© - ¥ó¥È¤Ç¸½ºß¤Îʸ»ú¤¬É½¼¨¤Ç¤­¤ì¤Ð¡¢¤½¤Î¥Õ¥©¥ó¥È¤ò»È¤¦¡£¤½¤¦¤Ç¤Ê - ¤±¤ì¤Ð¡¢¼¡¤Î¥¹¥Æ¥Ã¥×¤Ë¿Ê¤à¡£ - -
  3. ¸½ºß¤Îʸ»ú¼«¿È¤ò»È¤Ã¤Æ¡¢¤½¤Î¥Õ¥©¥ó¥È¥»¥Ã¥È¤Î¥Þ¥Ã¥Ô¥ó¥°¥Æ¡¼¥Ö - ¥ë¤ò¤Ò¤¯¡£¥Õ¥©¥ó¥È¤¬¸«¤Ä¤«¤ì¤Ð¤½¤ì¤ò»È¤¦¡£ - -
- - °Ê¾å¤Î¥¢¥ë¥´¥ê¥º¥à¤Ç¥Õ¥©¥ó¥È¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¤½¤Îʸ»ú - ¤È¤·¤Æ¶õ¤Î»Í³Ñ·Á¤òɽ¼¨¤¹¤ë¡£ - - ¤³¤Î´Ø¿ô¤¬ÉÁ²è¤¹¤ë¤Î¤Ï¥°¥ê¥Õ¤ÎÁ°·Ê¿§¤À¤±¤Ç¤¢¤ë¡£ÇØ·Ê¿§¤ò»ØÄꤹ¤ë¤Ë - ¤Ï¡¢´Ø¿ô mdraw_image_text () ¤ò»È¤¦¤³¤È¡£ - - ¤³¤Î´Ø¿ô¤Ï¡¢X ¥¦¥£¥ó¥É¥¦¤Ë¤ª¤±¤ë XDrawString (), - XmbDrawString (), XwcDrawString () ¤ËÁêÅö¤¹¤ë¡£ - - @return - ½èÍý¤¬À®¸ù¤·¤¿¾ì¹ç¡¢mdraw_text () ¤Ï 0 ÊÖ¤¹¡£¥¨¥é¡¼¤¬¸¡½Ð¤µ¤ì¤¿¾ì - ¹ç¤Ï -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô @c merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ - - @latexonly \IPAlabel{mdraw_text} @endlatexonly */ - -/*** - @errors - @c MERROR_RANGE - - @seealso - mdraw_image_text () */ - -int -mdraw_text (MFrame *frame, MDrawWindow win, int x, int y, - MText *mt, int from, int to) -{ - MDrawControl control; - - memset (&control, 0, sizeof control); - control.as_image = 0; - return draw_text (frame, win, x, y, mt, from, to, &control); -} - -/*=*/ - - -/***en - @brief Draw an M-text on a window as an image - - The mdraw_image_text () function draws the text between $FROM and - $TO of M-text $MT as image on window $WIN of frame $FRAME at - coordinate ($X, $Y). - - The way to draw a text is the same as in mdraw_text () except that - this function also draws the background with the color specified - by faces. - - This function is the counterpart of XDrawImageString (), - XmbDrawImageString (), and XwcDrawImageString () - functions in the X Window System. - - @return - If the operation was successful, mdraw_image_text () returns 0. - If an error is detected, it returns -1 and assigns an error code - to the external variable @c merror_code. */ - -/***ja - @brief ¥Ç¥£¥¹¥×¥ì¥¤¤ËM-text ¤ò²èÁü¤È¤·¤ÆÉÁ¤¯ - - ´Ø¿ô mdraw_image_text () ¤Ï¡¢¥Õ¥ì¡¼¥à $FRAME ¤Î¥¦¥£¥ó¥É¥¦ $WIN ¤Î - ºÂɸ ($X, $Y) ¤Ë¡¢M-text $MT ¤Î $FROM ¤«¤é $TO ¤Þ¤Ç¤Î¥Æ¥­¥¹¥È¤ò²è - Áü¤È¤·¤ÆÉÁ¤¯¡£ - - ¥Æ¥­¥¹¥È¤ÎÉÁ²èÊýË¡¤Ï mdraw_text () ¤È¤Û¤ÜƱ¤¸¤Ç¤¢¤ë¤¬¡¢¤³¤Î´Ø¿ô¤Ç - ¤Ï $FACE ¤Ç»ØÄꤵ¤ì¤¿¿§¤ÇÇطʤâÉÁ¤¯ÅÀ¤¬°Û¤Ê¤Ã¤Æ¤¤¤ë¡£ - - ¤³¤Î´Ø¿ô¤Ï¡¢X ¥¦¥£¥ó¥É¥¦¤Ë¤ª¤±¤ë XDrawImageString (), - XmbDrawImageString (), XwcDrawImageString () ¤Ë - ÁêÅö¤¹¤ë¡£ - - @return - ½èÍý¤¬À®¸ù¤·¤¿¾ì¹ç¡¢mdraw_image_text () ¤Ï 0 ¤òÊÖ¤¹¡£¥¨¥é¡¼¤¬¸¡½Ð - ¤µ¤ì¤¿¾ì¹ç¤Ï -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô @c m_errro ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ - ¤ë¡£ - - @latexonly \IPAlabel{mdraw_image_text} @endlatexonly */ - -/*** - @errors - @c MERROR_RANGE - - @seealso - mdraw_text () */ - -int -mdraw_image_text (MFrame *frame, MDrawWindow win, int x, int y, - MText *mt, int from, int to) -{ - MDrawControl control; - - memset (&control, 0, sizeof control); - control.as_image = 1; - return draw_text (frame, win, x, y, mt, from, to, &control); -} - -/*=*/ - -/***en - @brief Draw an M-text on a window with fine control. - - The mdraw_text_with_control () function draws the text between - $FROM and $TO of M-text $MT on windows $WIN of frame $FRAME at - coordinate ($X, $Y). - - The way to draw a text is the same as in mdraw_text () except that - this function also follows what specified in the drawing control - object $CONTROL. - - For instance, if of $CONTROL is nonzero, this - function draw an M-text 2-dimensionally, i.e., newlines in M-text - breaks lines and the following characters are drawn in the next - line. See the documentation of the structure @ MDrawControl for - more detail. */ - -int -mdraw_text_with_control (MFrame *frame, MDrawWindow win, int x, int y, - MText *mt, int from, int to, MDrawControl *control) -{ - return draw_text (frame, win, x, y, mt, from, to, control); -} - -/*=*/ - -/***en - @brief Compute text pixel width. - - The mdraw_text_extents () function computes the width of text - between $FROM and $TO of M-text $MT when it is drawn on a window - of frame $FRAME using the mdraw_text_with_control () function with - the drawing control object $CONTROL. - - If $OVERALL_INK_RETURN is not @c NULL, this function also computes - the bounding box of character ink of the M-text, and stores the - results in the members of the structure pointed to by - $OVERALL_INK_RETURN. If the M-text has a face specifying a - surrounding box, the box is included in the bounding box. - - If $OVERALL_LOGICAL_RETURN is not @c NULL, this function also - computes the bounding box that provides mininum spacing to other - graphical features (such as surrounding box) for the M-text, and - stores the results in the members of the structure pointed to by - $OVERALL_LOGICAL_RETURN. - - If $OVERALL_LINE_RETURN is not @c NULL, this function also - computes the bounding box that provides mininum spacing to the - other M-text drawn, and stores the results in the members of the - structure pointed to by $OVERALL_LINE_RETURN. This is a union of - $OVERALL_INK_RETURN and $OVERALL_LOGICAL_RETURN if the members - min_line_ascent, min_line_descent, max_line_ascent, and - max_line_descent of $CONTROL are all zero. - - @return - - This function returns the width of the text to be drawn in the - unit of pixels. If $CONTROL->two_dimensional is nonzero and the - text is drawn in multiple physical lines, it returns the width of - the widest line. If an error occurs, it returns -1 and assigns an - error code to the external variable @c merror_code. */ - -/***ja - @brief ¥Æ¥­¥¹¥È¤ÎÉý¤ò·×»»¤¹¤ë - - ´Ø¿ô mdraw_text_extents () ¤Ï¡¢M-text $MT ¤Î $FROM ¤«¤é $TO ¤Þ¤Ç¤ò - ¥Õ¥ì¡¼¥à $FRAME ¤Ëɽ¼¨¤¹¤ëºÝ¤ËɬÍפȤʤëÉý¤òÊÖ¤¹¡£ - - ¥Ý¥¤¥ó¥¿ $OVERALL_RETURN ¤¬ @c NULL °Ê³°¤Î¾ì¹ç¡¢¤³¤Î´Ø¿ô¤Ï¥Æ¥­¥¹¥È - Á´ÂΤÎɽ¼¨ÈϰϾðÊó¤â·×»»¤·¡¢$OVERALL_RETURN ¤¬»Ø¤¹¹½Â¤ÂΤΥá¥ó¥Ð¤Ë - ¤½¤Î·ë²Ì¤òÀßÄꤹ¤ë¡£ - - @return - ¤³¤Î´Ø¿ô¤Ïɽ¼¨¤ËɬÍפȤʤë¥Æ¥­¥¹¥È¤ÎÉý¤ò¥Ô¥¯¥»¥ëñ°Ì¤ÇÊÖ¤¹¡£¥¨¥é¡¼ - ¤¬À¸¤¸¤¿¾ì¹ç¤Ï -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô @c merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤ò - ÀßÄꤹ¤ë¡£ - - @latexonly \IPAlabel{mdraw_text_extents} @endlatexonly */ - -/*** - @errors - @c MERROR_RANGE */ - -int -mdraw_text_extents (MFrame *frame, - MText *mt, int from, int to, MDrawControl *control, - MDrawMetric *overall_ink_return, - MDrawMetric *overall_logical_return, - MDrawMetric *overall_line_return) -{ - MGlyphString *gstring; - int y = 0; - int width, rbearing; - - ASSURE_CONTROL (control); - M_CHECK_POS_X (mt, from, -1); - if (to > mtext_nchars (mt) + (control->cursor_width != 0)) - to = mtext_nchars (mt) + (control->cursor_width != 0); - else if (to < from) - to = from; - - gstring = get_gstring (frame, mt, from, to, control); - if (! gstring) - MERROR (MERROR_DRAW, -1); - width = gstring_width (gstring, from, to, &rbearing); - if (overall_ink_return) - { - overall_ink_return->y = - gstring->physical_ascent; - overall_ink_return->x = gstring->lbearing; - } - if (overall_logical_return) - { - overall_logical_return->y = - gstring->ascent; - overall_logical_return->x = 0; - } - if (overall_line_return) - { - overall_line_return->y = - gstring->line_ascent; - overall_line_return->x = gstring->lbearing; - } - - for (from = gstring->to; from < to; from = gstring->to) - { - int this_width, this_rbearing; - - y += gstring->line_descent; - M17N_OBJECT_UNREF (gstring->top); - gstring = get_gstring (frame, mt, from, to, control); - this_width = gstring_width (gstring, from, to, &this_rbearing); - y += gstring->line_ascent; - if (width < this_width) - width = this_width; - if (rbearing < this_rbearing) - rbearing = this_rbearing; - } - if (overall_ink_return) - { - overall_ink_return->width = rbearing; - overall_ink_return->height - = y + gstring->physical_descent - overall_ink_return->y; - } - if (overall_logical_return) - { - overall_logical_return->width = width; - overall_logical_return->height - = y + gstring->descent - overall_logical_return->y; - } - if (overall_line_return) - { - overall_line_return->width = MAX (width, rbearing); - overall_line_return->height - = y + gstring->line_descent - overall_line_return->y; - } - - M17N_OBJECT_UNREF (gstring->top); - return width; -} - -/*=*/ - -/***en - @brief Compute the text dimensions of each character of M-text. - - The mdraw_text_per_char_extents () function computes the drawn - metric of each character between $FROM and $TO of M-text $MT - assuming that they are drawn on a window of frame $FRAME using the - mdraw_text_with_control () function with the drawing control - object $CONTROL. - - $ARRAY_SIZE specifies the size of $INK_ARRAY_RETURN and - $LOGICAL_ARRAY_RETURN. Each successive element of - $INK_ARRAY_RETURN and $LOGICAL_ARRAY_RETURN are set to the drawn - ink and logical metrics of successive characters respectively, - relative to the drawing origin of the M-text. The number of - elements of $INK_ARRAY_RETURN and $LOGICAL_ARRAY_RETURN that have - been set is returned to $NUM_CHARS_RETURN. - - If $ARRAY_SIZE is too small to return all metrics, the function - returns -1 and store the requested size in $NUM_CHARS_RETURN. - Otherwise, it returns zero. - - If pointer $OVERALL_INK_RETURN an $OVERALL_LOGICAL_RETURN are not - @c NULL, this function also computes the metrics of the overall - text and stores the results in the members of the structure - pointed to by $OVERALL_INK_RETURN and $OVERALL_LOGICAL_RETURN. - - If $CONTROL->two_dimensional is nonzero, this function computes - only the metrics of characters in the first line. */ - -int -mdraw_text_per_char_extents (MFrame *frame, - MText *mt, int from, int to, - MDrawControl *control, - MDrawMetric *ink_array_return, - MDrawMetric *logical_array_return, - int array_size, - int *num_chars_return, - MDrawMetric *overall_ink_return, - MDrawMetric *overall_logical_return) -{ - MGlyphString *gstring; - MGlyph *g; - int x; - - ASSURE_CONTROL (control); - *num_chars_return = to - from; - if (array_size < *num_chars_return) - return 0; - if (overall_logical_return) - memset (overall_logical_return, 0, sizeof (MDrawMetric)); - if (overall_ink_return) - memset (overall_ink_return, 0, sizeof (MDrawMetric)); - - M_CHECK_RANGE (mt, from, to, -1, 0); - gstring = get_gstring (frame, mt, from, to, control); - if (! gstring) - { - *num_chars_return = 0; - return 0; - } - - for (g = MGLYPH (1), x = 0; g->type != GLYPH_ANCHOR;) - if (g->pos >= from && g->pos < to) - { - int start = g->pos; - int end = g->to; - int width = g->width; - int lbearing = g->lbearing; - int rbearing = g->rbearing; - int ascent = g->ascent; - int descent = g->descent; - int logical_ascent = g->rface->rfont->ascent; - int logical_descent = g->rface->rfont->descent; - - for (g++; g->type != GLYPH_ANCHOR && g->pos == start; g++) - { - if (lbearing < width + g->lbearing) - lbearing = width + g->lbearing; - if (rbearing < width + g->rbearing) - rbearing = width + g->rbearing; - width += g->width; - if (ascent < g->ascent) - ascent = g->ascent; - if (descent < g->descent) - descent = g->descent; - } - - if (end > to) - end = to; - while (start < end) - { - ink_array_return[start - from].x = x + lbearing; - ink_array_return[start - from].y = - ascent; - ink_array_return[start - from].width = rbearing - lbearing; - ink_array_return[start - from].height = ascent + descent; - logical_array_return[start - from].x = x; - logical_array_return[start - from].y = - logical_descent; - logical_array_return[start - from].height - = logical_ascent + logical_descent; - logical_array_return[start - from].width = width; - start++; - } - x += width; - } - - if (overall_ink_return) - { - overall_ink_return->y = - gstring->line_ascent; - overall_ink_return->x = gstring->lbearing; - overall_ink_return->width = x - gstring->lbearing; - overall_ink_return->height = gstring->height; - } - if (overall_logical_return) - { - overall_logical_return->y = - gstring->ascent; - overall_logical_return->x = 0; - overall_logical_return->width = x; - overall_logical_return->height = gstring->ascent + gstring->descent; - } - - M17N_OBJECT_UNREF (gstring->top); - return 1; -} - -/*=*/ - -/***en - @brief Return the character position nearest to the coordinates. - - The mdraw_coordinates_position () function checks which character - is to be drawn at coordinate ($X, $Y) when the text between $FROM - and $TO of M-text $MT is drawn at the coordinate (0, 0) using the - mdraw_text_with_control () function with the drawing control - object $CONTROL. Here, the character position means the number of - characters that precede the character in question in $MT. - - $FRAME is used only to get the default face information. - - @return - If the glyph image of a character covers coordinate ($X, $Y), - mdraw_coordinates_position () returns the character position of - that character.\n\n - If $Y is less than the minimum Y-coordinate of the drawn area, it - returns $FROM.\n\n\n - If $Y is greater than the maximum Y-coordinate of the drawn area, - it returns $TO.\n\n\n - If $Y fits in with the drawn area but $X is less than the minimum - X-coordinate, it returns the character position of the first - character drawn on the line $Y.\n\n\n - If $Y fits in with the drawn area but $X is greater than the - maximum X-coordinate, it returns the character position of the - last character drawn on the line $Y. */ - -/***ja - @brief »ØÄꤷ¤¿ºÂɸ¤Ë¤¢¤ëʸ»ú¤Î°ÌÃÖ¤òÆÀ¤ë - - ´Ø¿ô mdraw_coordinates_position () ¤Ï¡¢ - - @li ´Ø¿ô mdraw_text () ¤ò»È¤Ã¤Æ - @li M-text $MT ¤Î $FROM ¤«¤é $TO ¤Þ¤Ç¤ò - @li ºÂɸ (0, 0) ¤òµ¯ÅÀ¤È¤·¤Æ²¾¤ËÉÁ²è¤·¤¿¾ì¹ç - - ºÂɸ ($X, $Y) ¤ËÉÁ²è¤µ¤ì¤ë¥Ù¤­Ê¸»ú¤Îʸ»ú°ÌÃÖ¤òÊÖ¤¹¡£¤³¤³¤Çʸ»ú°ÌÃÖ - ¤È¤Ï¡¢Åö³º M-text Ãæ¤Ë¤ª¤¤¤Æ¤½¤Îʸ»ú¤¬ºÇ½é¤«¤é²¿ÈÖÌܤ«¤ò¼¨¤¹À°¿ô¤Ç - ¤¢¤ë¡£¤¿¤À¤·ºÇ½é¤Îʸ»ú¤Îʸ»ú°ÌÃÖ¤Ï0¤È¤¹¤ë¡£ - - $FRAME ¤Ï¥Ç¥Õ¥©¥ë¥È¥Õ¥§¡¼¥¹¤Î¾ðÊó¤òÆÀ¤ë¤¿¤á¤À¤±¤ËÍѤ¤¤é¤ì¤ë¡£ - - @return - ºÂɸ ($X, $Y) ¤¬¤¢¤ëʸ»ú¤Î¥°¥ê¥Õ¤Çʤ¤ï¤ì¤ë¾ì¹ç¡¢ ´Ø¿ô - mdraw_coordinates_position () ¤Ï¤½¤Îʸ»ú¤Îʸ»ú°ÌÃÖ¤òÊÖ¤¹¡£ - - ¤â¤· $Y ¤¬ÉÁ²èÎΰè¤ÎºÇ¾®YºÂɸ¤è¤ê¤â¾®¤µ¤¤¤Ê¤é¤Ð $FROM ¤òÊÖ¤¹¡£ - - ¤â¤· $Y ¤¬ÉÁ²èÎΰè¤ÎºÇÂçYºÂɸ¤è¤ê¤âÂ礭¤¤¤Ê¤é¤Ð $TO ¤òÊÖ¤¹¡£ - - ¤â¤· $Y ¤¬ÉÁ²èÎΰè¤Ë¾è¤Ã¤Æ¤¤¤Æ¤«¤Ä $X ¤¬ÉÁ²èÎΰè¤ÎºÇ¾®XºÂɸ¤è¤ê¤â - ¾®¤µ¤¤¾ì¹ç¤Ï¡¢Ä¾Àþ y = $Y ¾å¤ËÉÁ²è¤µ¤ì¤ëºÇ½é¤Îʸ»ú¤Îʸ»ú°ÌÃÖ¤òÊÖ¤¹¡£ - - ¤â¤· $Y ¤¬ÉÁ²èÎΰè¤Ë¾è¤Ã¤Æ¤¤¤Æ¤«¤Ä $X ¤¬ÉÁ²èÎΰè¤ÎºÇÂçXºÂɸ¤è¤ê¤â - Â礭¤¤¾ì¹ç¤Ï¡¢Ä¾Àþ y = $Y ¾å¤ËÉÁ²è¤µ¤ì¤ëºÇ¸å¤Îʸ»ú¤Îʸ»ú°ÌÃÖ¤òÊÖ¤¹¡£ */ - -int -mdraw_coordinates_position (MFrame *frame, MText *mt, int from, int to, - int x_offset, int y_offset, MDrawControl *control) -{ - MGlyphString *gstring; - int y = 0; - int width; - MGlyph *g; - - M_CHECK_POS_X (mt, from, -1); - if (to > mtext_nchars (mt) + (control->cursor_width != 0)) - to = mtext_nchars (mt) + (control->cursor_width != 0); - else if (to < from) - to = from; - - if (from == to) - return from; - ASSURE_CONTROL (control); - gstring = get_gstring (frame, mt, from, to, control); - while (y + gstring->line_descent <= y_offset - && gstring->to < to) - { - from = gstring->to; - y += gstring->line_descent; - M17N_OBJECT_UNREF (gstring->top); - gstring = get_gstring (frame, mt, from, to, control); - y += gstring->line_ascent; - } - - /* Accumulate width of glyphs in WIDTH until it exceeds X. */ - if (! control->orientation_reversed) - { - width = gstring->indent; - for (g = MGLYPH (1); g[1].type != GLYPH_ANCHOR; g++) - if (g->pos >= from && g->pos < to) - { - width += g->width; - if (width > x_offset) - break; - } - } - else - { - width = - gstring->indent; - for (g = MGLYPH (gstring->used - 2); g->type != GLYPH_ANCHOR; g--) - if (g->pos >= from && g->pos < to) - { - width -= g->width; - if (width < x_offset) - break; - } - } - from = g->pos; - M17N_OBJECT_UNREF (gstring->top); - - return from; -} - -/*=*/ - -/***en - @brief Compute information about a glyph. - - The @c mdraw_glyph_info () function computes information about a - glyph that covers a character at position $POS of the M-text $MT - assuming that the text is drawn from the character at $FROM of $MT - on a window of frame $FRAME using the mdraw_text_with_control () - function with the drawing control object $CONTROL. - - The information is stored in the members of $INFO. */ - -/*** - @seealso - MDrawGlyphInfo -*/ - -int -mdraw_glyph_info (MFrame *frame, MText *mt, int from, int pos, - MDrawControl *control, MDrawGlyphInfo *info) -{ - MGlyphString *gstring; - MGlyph *g; - int y = 0; - - M_CHECK_RANGE_X (mt, from, pos, -1); - - ASSURE_CONTROL (control); - gstring = get_gstring (frame, mt, from, pos + 1, control); - if (! gstring) - MERROR (MERROR_DRAW, -1); - while (gstring->to <= pos) - { - y += gstring->line_descent; - M17N_OBJECT_UNREF (gstring->top); - gstring = get_gstring (frame, mt, gstring->to, pos + 1, control); - y += gstring->line_ascent; - } - info->line_from = gstring->from; - if (info->line_from < from) - info->line_from = from; - info->line_to = gstring->to; - - info->y = y; - if (! control->orientation_reversed) - { - info->x = gstring->indent; - for (g = MGLYPH (1); g->pos > pos || g->to <= pos; g++) - info->x += g->width; - } - else - { - info->x = - gstring->indent; - for (g = MGLYPH (gstring->used - 2); g->pos > pos || g->to <= pos; g--) - info->x -= g->width; - while (g[-1].to == g->to) - g--; - } - info->from = g->pos; - info->to = g->to; - info->this.x = g->lbearing; - info->this.y = - gstring->line_ascent; - info->this.height = gstring->height; - if (g->rface->rfont) - info->font = &g->rface->rfont->font; - else - info->font = NULL; - /* info->this.width is calculated later. */ - - if (info->from > info->line_from) - { - /* The logically previous glyph is on this line. */ - MGlyph *g_tmp = find_glyph_in_gstring (gstring, info->from - 1, 1); - - info->prev_from = g_tmp->pos; - } - else if (info->line_from > 0) - { - /* The logically previous glyph is on the previous line. */ - MGlyphString *gst = get_gstring (frame, mt, gstring->from - 1, - gstring->from, control); - MGlyph *g_tmp = find_glyph_in_gstring (gst, info->from - 1, 1); - - info->prev_from = g_tmp->pos; - M17N_OBJECT_UNREF (gst->top); - } - else - info->prev_from = -1; - - if (GLYPH_INDEX (g) > 1) - info->left_from = g[-1].pos, info->left_to = g[-1].to; - else if (! control->orientation_reversed) - { - if (info->line_from > 0) - { - MGlyph *g_tmp; - MGlyphString *gst; - int p = gstring->from - 1; - - gst = get_gstring (frame, mt, p, gstring->from, control); - g_tmp = gst->glyphs + (gst->used - 2); - info->left_from = g_tmp->pos, info->left_to = g_tmp->to; - M17N_OBJECT_UNREF (gst->top); - } - else - info->left_from = info->left_to = -1; - } - else - { - if (gstring->to + (control->cursor_width == 0) <= mtext_nchars (mt)) - { - MGlyph *g_tmp; - MGlyphString *gst; - int p = gstring->to; - - gst = get_gstring (frame, mt, p, p + 1, control); - g_tmp = gst->glyphs + (gst->used - 2); - info->left_from = g_tmp->pos, info->left_to = g_tmp->to; - M17N_OBJECT_UNREF (gst->top); - } - else - info->left_from = info->left_to = -1; - } - - if (info->to < gstring->to) - { - /* The logically next glyph is on this line. */ - MGlyph *g_tmp = find_glyph_in_gstring (gstring, info->to, 0); - - info->next_to = g_tmp->to; - } - else if (info->to + (control->cursor_width == 0) <= mtext_nchars (mt)) - { - /* The logically next glyph is on the next line. */ - int p = info->to; - MGlyphString *gst = get_gstring (frame, mt, p, p + 1, control); - MGlyph *g_tmp = find_glyph_in_gstring (gst, p, 0); - - info->next_to = g_tmp->to; - M17N_OBJECT_UNREF (gst->top); - } - else - info->next_to = -1; - - for (info->this.width = (g++)->width; - g->pos == pos && g->type != GLYPH_ANCHOR; - info->this.width += (g++)->width); - - if (g->type != GLYPH_ANCHOR) - info->right_from = g->pos, info->right_to = g->to; - else if (! control->orientation_reversed) - { - if (gstring->to + (control->cursor_width == 0) <= mtext_nchars (mt)) - { - pos = gstring->to; - M17N_OBJECT_UNREF (gstring->top); - gstring = get_gstring (frame, mt, pos, pos + 1, control); - g = MGLYPH (1); - info->right_from = g->pos, info->right_to = g->to; - } - else - info->right_from = info->right_to = -1; - } - else - { - if (info->line_from > 0) - { - pos = gstring->from - 1; - M17N_OBJECT_UNREF (gstring->top); - gstring = get_gstring (frame, mt, pos, pos + 1, control); - g = MGLYPH (1); - info->right_from = g->pos, info->right_to = g->to; - } - else - info->right_from = info->right_to = -1; - } - - M17N_OBJECT_UNREF (gstring->top); - return 0; -} - -/*=*/ - -/***en - @brief Draw one or more textitems. - - The mdraw_text_items () function draws one or more M-texts on - window $WIN of $FRAME at coordinate ($X, $Y). $ITEMS is an array - of the textitems to be drawn and $NITEMS is the number of - textimtems in the array. */ - -/***ja - @brief textitem ¤òɽ¼¨¤¹¤ë - - ´Ø¿ô mdraw_text_items () ¤Ï¡¢°ì¸Ä°Ê¾å¤Î¥Æ¥­¥¹¥È¥¢¥¤¥Æ¥à¤ò¡¢¥Õ¥ì¡¼ - ¥à $FRAME ¤Î¥¦¥£¥ó¥É¥¦ $WIN ¤ÎºÂɸ ($X, $Y) ¤Ëɽ¼¨¤¹¤ë¡£$ITEMS ¤Ï - ɽ¼¨¤¹¤Ù¤­¥Æ¥­¥¹¥È¥¢¥¤¥Æ¥à¤ÎÇÛÎó¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ê¡¢$NITEMS ¤Ï¤½¤Î - ¸Ä¿ô¤Ç¤¢¤ë¡£ - - @latexonly \IPAlabel{mdraw_text_items} @endlatexonly */ - -/*** - @seealso - MTextItem, mdraw_text (). */ - -void -mdraw_text_items (MFrame *frame, MDrawWindow win, int x, int y, - MDrawTextItem *items, int nitems) -{ - while (nitems-- > 0) - { - if (items->face) - mtext_push_prop (items->mt, 0, mtext_nchars (items->mt), Mface, - items->face); - mdraw_text_with_control (frame, win, x, y, - items->mt, 0, mtext_nchars (items->mt), - items->control); - x += mdraw_text_extents (frame, items->mt, 0, mtext_nchars (items->mt), - items->control, NULL, NULL, NULL); - x += items->delta; - if (items->face) - mtext_pop_prop (items->mt, 0, mtext_nchars (items->mt), Mface); - } -} - -/*=*/ - -int -mdraw_default_line_break (MText *mt, int pos, - int from, int to, int line, int y) -{ - int c = mtext_ref_char (mt, pos); - int orig_pos = pos; - - if (c == ' ' || c == '\t') - { - pos++; - while (pos < to - && ((c = mtext_ref_char (mt, pos)) == ' ' || c == '\t')) - pos++; - } - else - { - while (pos > from) - { - if (c == ' ' || c == '\t') - break; - pos--; - c = mtext_ref_char (mt, pos); - } - if (pos == from) - pos = orig_pos; - else - pos++; - } - return pos; -} - -/*=*/ - -/***en - @brief Obtain per character dimension information. - - The mdraw_per_char_extents () function computes the text dimension - of each character in M-text $MT. The faces given as text - properties in $MT and the default face of frame $FRAME determine - the fonts to draw the text. Each successive element in - $ARRAY_RETURN is set to the drawn metrics of successive - characters, which is relative to the origin of the drawing, and a - rectangle for each character in $MT. The number of elements of - $ARRAY_RETURN must be equal to or greater than the number of - characters in $MT. - - If pointer $OVERALL_RETURN is not @c NULL, this function also - computes the extents of the overall text and stores the results in - the members of the structure pointed to by $OVERALL_RETURN */ - -/***ja - @brief M-text ¤Îʸ»úËè¤Î¾ðÊó¤òÆÀ¤ë - - ´Ø¿ô mdraw_per_char_extents () ¤Ï¡¢M-text $MT Ãæ¤Î³Æʸ»ú¤Îɽ¼¨ÈÏ°Ï - ¤ò·×»»¤¹¤ë¡£¤³¤Î·×»»¤ËÍѤ¤¤ë¥Õ¥©¥ó¥È¤Ï¡¢$MT ¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Ç - »ØÄꤵ¤ì¤¿¥Õ¥§¡¼¥¹¤È¡¢¥Õ¥ì¡¼¥à $FRAME ¤Î¥Ç¥Õ¥©¥ë¥È¥Õ¥§¡¼¥¹¤«¤é·èÄê - ¤µ¤ì¤ë¡£$ARRAY_RETURN ¤Î³ÆÍ×ÁǤϡ¢Åö³º M-text Ãæ¤Î³Æʸ»ú¤Îɽ¼¨ÈÏ°Ï - ¾ðÊó¤Ë¤è¤Ã¤Æ½ç¤ËËä¤á¤é¤ì¤ë¡£¤³¤Îɽ¼¨ÈϰϾðÊó¤Ï¡¢M-text ¤Îɽ¼¨¸¶ÅÀ - ¤«¤é¤ÎÁêÂаÌÃ֤Ǥ¢¤ë¡£$ARRAY_RETURN ¤ÎÍ×ÁÇ¿ô¤Ï¡¢M-text ¤Îʸ»ú¿ô°Ê - ¾å¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ - - ¥Ý¥¤¥ó¥¿ $OVERALL_RETURN ¤¬ @c NULL ¤Ç¤Ê¤¤¾ì¹ç¤Ï¡¢¥Æ¥­¥¹¥ÈÁ´ÂΤÎɽ¼¨ - ÈϰϾðÊó¤â·×»»¤·¡¢¤½¤Î·×»»¤ò $OVERALL_RETURN ¤Î»Ø¤¹Àè¤Ë³ÊǼ¤¹¤ë¡£ - - @latexonly \IPAlabel{mdraw_per_char_extents} @endlatexonly */ - -void -mdraw_per_char_extents (MFrame *frame, MText *mt, - MDrawMetric *array_return, - MDrawMetric *overall_return) -{ -} - -void -mdraw_clear_cache (MText *mt) -{ - mtext_pop_prop (mt, 0, mtext_nchars (mt), M_glyph_string); -} - -/*** @} */ - -/* - Local Variables: - coding: euc-japan - End: -*/ diff --git a/src/font-flt.c b/src/font-flt.c deleted file mode 100644 index b93c5c4..0000000 --- a/src/font-flt.c +++ /dev/null @@ -1,1537 +0,0 @@ -/* font-flt.c -- Font Layout Table sub-module. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -#include "config.h" - -#include -#include -#include -#include -#include -#include - -#include "m17n-gui.h" -#include "m17n-misc.h" -#include "internal.h" -#include "mtext.h" -#include "symbol.h" -#include "plist.h" -#include "internal-gui.h" -#include "font.h" -#include "face.h" - -/* Font Layouter */ - -/* Font Layout Table (FLT) - -Predefined terms: SYMBOL, INTEGER, STRING - -FLT ::= '(' STAGE + ')' - -STAGE ::= CATEGORY-TABLE ? FONT-LAYOUT-RULE - -;; Each STAGE consumes a source (code sequence) and produces another -;; code sequence that is given to the next STAGE as a source. The -;; source given to the first stage is a sequence of character codes -;; that are assigned category codes by CATEGORY-TABLE. The output of -;; the last stage is a glyph code sequence given to the renderer. - -CATEGORY-TABLE ::= - '(' 'category' CATEGORY-SPEC + ')' -CATEGORY-SPEC ::= - '(' CODE [ CODE ] CATEGORY ')' -CODE ::= INTEGER -CATEGORY ::= INTEGER -;; ASCII character codes of alphabet ('A' .. 'Z' 'a' .. 'z'). -;; Ex: CATEGORY-TABLE -;; (category -;; (0x0900 0x097F ?E) ; All Devanagari characters -;; (0x093C ?N)) ; DEVANAGARI-LETTER NUKTA -;; Assign the category 'E' to all Devanagari characters but 0x093C, -;; assign the category 'N' to 0x093C. - -FONT-LAYOUT-RULE ::= - '(' 'generator' RULE MACRO-DEF * ')' - -RULE ::= COMMAND | REGEXP-RULE | MATCH-RULE | MAP-RULE - | COND-STRUCT | MACRO-NAME - -COMMAND ::= - DIRECT-CODE | COMBINING | PREDEFIND-COMMAND | OTF-COMMAND - -DIRECT-CODE ::= INTEGER -;; Always succeed. Produce the code. Consume no source. - -PREDEFIND-COMMAND ::= - '=' | '*' | '<' | '>' | '|' - -;; '=': Succeed when the current run contains at least one code. -;; Consume the first code in the current run, and produce it as is. - -;; '*': If the the previous command succeeded, repeat it until it -;; fails. - -;; '<': Produce a special code that indicates the start of grapheme -;; cluster. Succeed always, consume nothing. - -;; '>': Produce a special code that indicates the end of grapheme -;; cluster. Succeed always, consume nothing. - -;; '|': Produce a special code whose category is ' '. Succeed always, -;; consume nothing. - -OTF-COMMAND ::= - 'otf:''SCRIPT'[':'['LANGSYS'][':'[GSUB-FEATURES][':'GPOS-FEATURES]]] -;; Run the Open Type Layout Table on the current run. Succeed always, -;; consume nothing. - -SCRIPT ::= OTF-TAG -;; OTF's ScriptTag name (four letters) listed at: -;; -LANGSYS ::= OTF-TAG -;; OTF's Language System name (four letters) listed at: -;; - -GSUB-FEATURES ::= [FEATURE[,FEATURE]*] | ' ' -GPOS-FEATURES ::= [FEATURE[,FEATURE]*] | ' ' -FEATURE ::= OTF-TAG -;; OTF's Feature name (four letters) listed at: -;; - -OTF-TAG ::= PRINTABLE-CHAR PRINTABLE-CHAR PRINTABLE-CHAR PRINTABLE-CHAR - -;; Ex. OTF-COMMAND -;; 'otf:deva' -;; Run all features in the default langsys of 'deva' script. -;; 'otf:deva::nukt:haln' -;; Run all GSUB features, run 'nukt' and 'haln' GPOS features. -;; 'otf:deva:: :' -;; Run all GSUB features, run no GPOS features. - -REGEXP-RULE ::= - '(' REGEXP RULE * ')' - -;; Succeed if REGXP matches the head of source. Run RULEs while -;; limiting the source to the matching part. Consume that part. - -REGEXP ::= STRING -;; Must be composed only from ASCII characters. 'A' - 'Z', 'a' - 'z' -;; correspond to CATEGORY. - -;; Ex: REGEXP-RULE -;; ("VA?" -;; < | vowel * | >) - -MATCH-RULE ::= - '(' MATCH-IDX RULE * ')' - -;; Succeed if the previous REGEXP-RULE found a matching part for -;; MATCH-IDX. Run RULEs while limiting the source to the matching -;; part. If MATCH-IDX is zero, consume the whole part, else consume -;; nothing. - -MATCH-IDX ::= INTEGER -;; Must be 0..20. - -;; Ex. MATCH-RULE -;; (2 consonant *) - -MAP-RULE ::= - '(' ( SOURCE-SEQ | SOURCE-RANGE ) RULE * ')' - -;; Succeed if the source matches SOURCE-SEQ or SOURCE-RANGE. Run -;; RULEs while limiting the source to the matching part. Consume that -;; part. - -SOURCE-SEQ ::= - '(' CODE + ')' -SOURCE-RANGE ::= - '(' 'range' CODE CODE ')' -;; Ex. MAP-RULE -;; ((0x0915 0x094D) 0x43) -;; If the source code sequence is 0x0915 0x094D, produce 0x43. -;; ((range 0x0F40 0x0F6A) 0x2221) -;; If the first source code CODE is in the range 0x0F40..0x0F6A, -;; produce (0x2221 + (CODE - 0x0F40)). - -COND-STRUCT ::= - '(' 'cond' RULE + ')' - -;; Try each rule in sequence until one succeeds. Succeed if one -;; succeeds. Consume nothing. - -;; Ex. COND-STRUCT -;; (cond -;; ((0x0915 0x094D) 0x43) -;; ((range 0x0F40 0x0F6A) 0x2221) -;; = ) - -COMBINING ::= 'V''H''O''V''H' -V ::= ( 't' | 'c' | 'b' | 'B' ) -H ::= ( 'l' | 'c' | 'r' ) -O ::= ( '.' | XOFF | YOFF | XOFF YOFF ) -XOFF ::= '<'INTEGER | '>'INTEGER -YOFF ::= '+'INTEGER | '-'INTEGER -;; INTEGER must be integer 0..127 - -;; VH pair indicates 12 reference points of a glyph as below: -;; -;; 0----1----2 <---- ascent 0:tl (top-left) -;; | | 1:tc (top-center) -;; | | 2:tr (top-right) -;; | | 3:Bl (base-left) -;; 9 10 11 <---- center 4:Bc (base-center) -;; | | 5:Br (base-right) -;; --3----4----5-- <-- baseline 6:bl (bottom-left) -;; | | 7:bc (bottom-center) -;; 6----7----8 <---- descent 8:br (bottom-right) -;; 9:cl (center-left) -;; | | | 10:cc (center-center) -;; left center right 11:cr (center-right) -;; -;; Ex. COMBINING -;; 'tc.bc': -;; Align top-left point of the previous glyph and bottom-center -;; point of the current glyph. -;; 'Bl<20-10Br' -;; Align 20% left and 10% below of base-left point of the previous -;; glyph and base-right point of the current glyph. - -MACRO-DEF ::= - '(' MACRO-NAME RULE + ')' -MACRO-NAME ::= SYMBOL - -*/ - -static int mdebug_mask = MDEBUG_FONT_FLT; - -MSymbol Mlayouter; - -static MPlist *flt_list; - -/* Command ID: - 0 ... : direct code - -1 : invalid - -0x0F .. -2 : builtin commands - -0x100000F .. -0x10 : combining code - ... -0x1000010: index to FontLayoutStage->cmds - */ - -#define INVALID_CMD_ID -1 -#define CMD_ID_OFFSET_BUILTIN -2 -#define CMD_ID_OFFSET_COMBINING -0x10 -#define CMD_ID_OFFSET_INDEX -0x1000010 - -/* Builtin commands. */ -#define CMD_ID_COPY -2 /* '=' */ -#define CMD_ID_REPEAT -3 /* '*' */ -#define CMD_ID_CLUSTER_BEGIN -4 /* '<' */ -#define CMD_ID_CLUSTER_END -5 /* '>' */ -#define CMD_ID_SEPARATOR -6 /* '|' */ -#define CMD_ID_LEFT_PADDING -7 /* '[' */ -#define CMD_ID_RIGHT_PADDING -8 /* ']' */ - -#define CMD_ID_TO_COMBINING_CODE(id) (CMD_ID_OFFSET_COMBINING - (id)) -#define COMBINING_CODE_TO_CMD_ID(code) (CMD_ID_OFFSET_COMBINING - (code)) - -#define CMD_ID_TO_INDEX(id) (CMD_ID_OFFSET_INDEX - (id)) -#define INDEX_TO_CMD_ID(idx) (CMD_ID_OFFSET_INDEX - (idx)) - -static MSymbol Mcond, Mrange; - -#define GLYPH_CODE_P(code) \ - ((code) >= GLYPH_CODE_MIN && (code) <= GLYPH_CODE_MAX) - -#define GLYPH_CODE_INDEX(code) ((code) - GLYPH_CODE_MIN) - -enum FontLayoutCmdRuleSrcType - { - SRC_REGEX, - SRC_INDEX, - SRC_SEQ, - SRC_RANGE - }; - -typedef struct -{ - enum FontLayoutCmdRuleSrcType src_type; - union { - struct { - char *pattern; - regex_t preg; - } re; - int match_idx; - struct { - int n_codes; - int *codes; - } seq; - struct { - int from, to; - } range; - } src; - - int n_cmds; - int *cmd_ids; -} FontLayoutCmdRule; - -typedef struct -{ - int n_cmds; - int *cmd_ids; -} FontLayoutCmdCond; - -typedef struct -{ - MSymbol script; - MSymbol langsys; - MSymbol gsub_features; - MSymbol gpos_features; -} FontLayoutCmdOTF; - -enum FontLayoutCmdType - { - FontLayoutCmdTypeRule, - FontLayoutCmdTypeCond, - FontLayoutCmdTypeOTF, - FontLayoutCmdTypeMAX - }; - -typedef struct -{ - enum FontLayoutCmdType type; - union { - FontLayoutCmdRule rule; - FontLayoutCmdCond cond; - FontLayoutCmdOTF otf; - } body; -} FontLayoutCmd; - -typedef struct -{ - MCharTable *category; - int size, inc, used; - FontLayoutCmd *cmds; -} FontLayoutStage; - -typedef MPlist MFontLayoutTable; /* t vs FontLayoutStage */ - -/* Font layout table loader */ - -/* Load a category table from PLIST. PLIST has this form: - PLIST ::= ( FROM-CODE TO-CODE ? CATEGORY-CHAR ) * -*/ - -static MCharTable * -load_category_table (MPlist *plist) -{ - MCharTable *table; - - table = mchartable (Minteger, (void *) 0); - - MPLIST_DO (plist, plist) - { - MPlist *elt; - int from, to, category_code; - - if (! MPLIST_PLIST (plist)) - MERROR (MERROR_FONT, NULL); - elt = MPLIST_PLIST (plist); - if (! MPLIST_INTEGER_P (elt)) - MERROR (MERROR_FONT, NULL); - from = MPLIST_INTEGER (elt); - elt = MPLIST_NEXT (elt); - if (! MPLIST_INTEGER_P (elt)) - MERROR (MERROR_FONT, NULL); - to = MPLIST_INTEGER (elt); - elt = MPLIST_NEXT (elt); - if (MPLIST_TAIL_P (elt)) - { - category_code = to; - to = from; - } - else - { - if (! MPLIST_INTEGER_P (elt)) - MERROR (MERROR_FONT, NULL); - category_code = MPLIST_INTEGER (elt); - } - if (! isalpha (category_code)) - MERROR (MERROR_FONT, NULL); - - if (from == to) - mchartable_set (table, from, (void *) category_code); - else - mchartable_set_range (table, from, to, (void *) category_code); - } - - return table; -} - - -/* Parse OTF command name NAME and store the result in CMD. - NAME has this form: - :SCRIPT[/[LANGSYS][=[GSUB-FEATURES][+GPOS-FEATURES]]] - where GSUB-FEATURES and GPOS-FEATURES have this form: - [FEATURE[,FEATURE]*] | ' ' */ - -static int -load_otf_command (FontLayoutCmd *cmd, char *name) -{ - char *p = name, *beg; - - cmd->type = FontLayoutCmdTypeOTF; - cmd->body.otf.script = cmd->body.otf.langsys = Mnil; - cmd->body.otf.gsub_features = cmd->body.otf.gpos_features = Mt; - - while (*p) - { - if (*p == ':') - { - for (beg = ++p; *p && *p != '/' && *p != '=' && *p != '+'; p++); - if (beg < p) - cmd->body.otf.script = msymbol__with_len (beg, p - beg); - } - else if (*p == '/') - { - for (beg = ++p; *p && *p != '=' && *p != '+'; p++); - if (beg < p) - cmd->body.otf.langsys = msymbol__with_len (beg, p - beg); - } - else if (*p == '=') - { - for (beg = ++p; *p && *p != '+'; p++); - if (beg < p) - cmd->body.otf.gsub_features = msymbol__with_len (beg, p - beg); - else - cmd->body.otf.gsub_features = Mnil; - } - else if (*p == '+') - { - for (beg = ++p; *p && *p != '+'; p++); - if (beg < p) - cmd->body.otf.gpos_features = msymbol__with_len (beg, p - beg); - else - cmd->body.otf.gpos_features = Mnil; - } - else - p++; - } - - return (cmd->body.otf.script == Mnil ? -1 : 0); -} - - -/* Read a decimal number from STR preceded by one of "+-><". '+' and - '>' means a plus sign, '-' and '<' means a minus sign. If the - number is greater than 127, limit it to 127. */ - -static int -read_decimal_number (char **str) -{ - char *p = *str; - int sign = (*p == '-' || *p == '<') ? -1 : 1; - int n = 0; - - p++; - while (*p >= '0' && *p <= '9') - n = n * 10 + *p++ - '0'; - *str = p; - if (n == 0) - n = 5; - return (n < 127 ? n * sign : 127 * sign); -} - - -/* Read a horizontal and vertical combining positions from STR, and - store them in the place pointed by X and Y. The horizontal - position left, center, and right are represented by 0, 1, and 2 - respectively. The vertical position top, center, bottom, and base - are represented by 0, 1, 2, and 3 respectively. If successfully - read, return 0, else return -1. */ - -static int -read_combining_position (char *str, int *x, int *y) -{ - int c = *str++; - int i; - - /* Vertical position comes first. */ - for (i = 0; i < 4; i++) - if (c == "tcbB"[i]) - { - *y = i; - break; - } - if (i == 4) - return -1; - c = *str; - /* Then comse horizontal position. */ - for (i = 0; i < 3; i++) - if (c == "lcr"[i]) - { - *x = i; - return 0; - } - return -1; -} - - -/* Return a combining code corresponding to SYM. */ - -static int -get_combining_command (MSymbol sym) -{ - char *str = msymbol_name (sym); - int base_x, base_y, add_x, add_y, off_x, off_y; - int c; - - if (read_combining_position (str, &base_x, &base_y) < 0) - return 0; - str += 2; - c = *str; - if (c == '.') - { - off_x = off_y = 128; - str++; - } - else - { - if (c == '+' || c == '-') - { - off_y = read_decimal_number (&str) + 128; - c = *str; - } - else - off_y = 128; - if (c == '<' || c == '>') - off_x = read_decimal_number (&str) + 128; - else - off_x = 128; - } - if (read_combining_position (str, &add_x, &add_y) < 0) - return 0; - - c = MAKE_COMBINING_CODE (base_y, base_x, add_y, add_x, off_y, off_x); - return (COMBINING_CODE_TO_CMD_ID (c)); -} - - -/* Load a command from PLIST into STAGE, and return that - identification number. If ID is not INVALID_CMD_ID, that means we - are loading a top level command or a macro. In that case, use ID - as the identification number of the command. Otherwise, generate a - new id number for the command. MACROS is a list of raw macros. */ - -static int -load_command (FontLayoutStage *stage, MPlist *plist, - MPlist *macros, int id) -{ - int i; - - if (MPLIST_INTEGER_P (plist)) - { - int code = MPLIST_INTEGER (plist); - - if (code < 0) - MERROR (MERROR_DRAW, INVALID_CMD_ID); - return code; - } - else if (MPLIST_PLIST_P (plist)) - { - /* PLIST ::= ( cond ... ) | ( STRING ... ) | ( INTEGER ... ) - | ( ( INTEGER INTEGER ) ... ) - | ( ( range INTEGER INTEGER ) ... ) */ - MPlist *elt = MPLIST_PLIST (plist); - int len = MPLIST_LENGTH (elt) - 1; - FontLayoutCmd *cmd; - - if (id == INVALID_CMD_ID) - { - FontLayoutCmd dummy; - id = INDEX_TO_CMD_ID (stage->used); - MLIST_APPEND1 (stage, cmds, dummy, MERROR_DRAW); - } - cmd = stage->cmds + CMD_ID_TO_INDEX (id); - - if (MPLIST_SYMBOL_P (elt)) - { - if (MPLIST_SYMBOL (elt) != Mcond) - MERROR (MERROR_DRAW, INVALID_CMD_ID); - elt = MPLIST_NEXT (elt); - cmd->type = FontLayoutCmdTypeCond; - cmd->body.cond.n_cmds = len; - MTABLE_CALLOC (cmd->body.cond.cmd_ids, len, MERROR_DRAW); - for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt)) - { - int this_id = load_command (stage, elt, macros, INVALID_CMD_ID); - - if (this_id == INVALID_CMD_ID) - MERROR (MERROR_DRAW, INVALID_CMD_ID); - /* The above load_command may relocate stage->cmds. */ - cmd = stage->cmds + CMD_ID_TO_INDEX (id); - cmd->body.cond.cmd_ids[i] = this_id; - } - } - else - { - cmd->type = FontLayoutCmdTypeRule; - if (MPLIST_MTEXT_P (elt)) - { - char *str = (char *) MTEXT_DATA (MPLIST_MTEXT (elt)); - - if (regcomp (&cmd->body.rule.src.re.preg, str, REG_EXTENDED)) - MERROR (MERROR_FONT, INVALID_CMD_ID); - cmd->body.rule.src_type = SRC_REGEX; - cmd->body.rule.src.re.pattern = strdup (str); - } - else if (MPLIST_INTEGER_P (elt)) - { - cmd->body.rule.src_type = SRC_INDEX; - cmd->body.rule.src.match_idx = MPLIST_INTEGER (elt); - } - else if (MPLIST_PLIST_P (elt)) - { - MPlist *pl = MPLIST_PLIST (elt); - int size = MPLIST_LENGTH (pl); - - if (MPLIST_INTEGER_P (pl)) - { - int i; - - cmd->body.rule.src_type = SRC_SEQ; - cmd->body.rule.src.seq.n_codes = size; - MTABLE_CALLOC (cmd->body.rule.src.seq.codes, size, - MERROR_FONT); - for (i = 0; i < size; i++, pl = MPLIST_NEXT (pl)) - { - if (! MPLIST_INTEGER_P (pl)) - MERROR (MERROR_DRAW, INVALID_CMD_ID); - cmd->body.rule.src.seq.codes[i] - = (unsigned) MPLIST_INTEGER (pl); - } - } - else if (MPLIST_SYMBOL_P (pl) && size == 3) - { - cmd->body.rule.src_type = SRC_RANGE; - pl = MPLIST_NEXT (pl); - if (! MPLIST_INTEGER_P (pl)) - MERROR (MERROR_DRAW, INVALID_CMD_ID); - cmd->body.rule.src.range.from - = (unsigned) MPLIST_INTEGER (pl); - pl = MPLIST_NEXT (pl); - if (! MPLIST_INTEGER_P (pl)) - MERROR (MERROR_DRAW, INVALID_CMD_ID); - cmd->body.rule.src.range.to - = (unsigned) MPLIST_INTEGER (pl); - } - else - MERROR (MERROR_DRAW, INVALID_CMD_ID); - } - else - MERROR (MERROR_DRAW, INVALID_CMD_ID); - - elt = MPLIST_NEXT (elt); - cmd->body.rule.n_cmds = len; - MTABLE_CALLOC (cmd->body.rule.cmd_ids, len, MERROR_DRAW); - for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt)) - { - int this_id = load_command (stage, elt, macros, INVALID_CMD_ID); - - if (this_id == INVALID_CMD_ID) - MERROR (MERROR_DRAW, INVALID_CMD_ID); - /* The above load_command may relocate stage->cmds. */ - cmd = stage->cmds + CMD_ID_TO_INDEX (id); - cmd->body.rule.cmd_ids[i] = this_id; - } - } - } - else if (MPLIST_SYMBOL_P (plist)) - { - MPlist *elt; - MSymbol sym = MPLIST_SYMBOL (plist); - char *name = msymbol_name (sym); - int len = strlen (name); - FontLayoutCmd cmd; - - if (len > 4 - && ! strncmp (name, "otf:", 4) - && load_otf_command (&cmd, name + 3) >= 0) - { - if (id == INVALID_CMD_ID) - { - id = INDEX_TO_CMD_ID (stage->used); - MLIST_APPEND1 (stage, cmds, cmd, MERROR_DRAW); - } - else - stage->cmds[CMD_ID_TO_INDEX (id)] = cmd; - return id; - } - - if (len == 1) - { - if (*name == '=') - return CMD_ID_COPY; - else if (*name == '*') - return CMD_ID_REPEAT; - else if (*name == '<') - return CMD_ID_CLUSTER_BEGIN; - else if (*name == '>') - return CMD_ID_CLUSTER_END; - else if (*name == '|') - return CMD_ID_SEPARATOR; - else if (*name == '[') - return CMD_ID_LEFT_PADDING; - else if (*name == ']') - return CMD_ID_RIGHT_PADDING; - else - id = 0; - } - else - { - id = get_combining_command (sym); - if (id) - return id; - } - - i = 1; - MPLIST_DO (elt, macros) - { - if (sym == MPLIST_SYMBOL (MPLIST_PLIST (elt))) - { - id = INDEX_TO_CMD_ID (i); - if (stage->cmds[i].type == FontLayoutCmdTypeMAX) - id = load_command (stage, MPLIST_NEXT (MPLIST_PLIST (elt)), - macros, id); - return id; - } - i++; - } - MERROR (MERROR_DRAW, INVALID_CMD_ID); - } - else - MERROR (MERROR_DRAW, INVALID_CMD_ID); - - return id; -} - -static void -free_flt_command (FontLayoutCmd *cmd) -{ - if (cmd->type == FontLayoutCmdTypeRule) - { - FontLayoutCmdRule *rule = &cmd->body.rule; - - if (rule->src_type == SRC_REGEX) - { - free (rule->src.re.pattern); - regfree (&rule->src.re.preg); - } - else if (rule->src_type == SRC_SEQ) - free (rule->src.seq.codes); - free (rule->cmd_ids); - } - else if (cmd->type == FontLayoutCmdTypeCond) - free (cmd->body.cond.cmd_ids); -} - -/* Load a generator from PLIST into a newly allocated FontLayoutStage, - and return it. PLIST has this form: - PLIST ::= ( COMMAND ( CMD-NAME COMMAND ) * ) -*/ - -static FontLayoutStage * -load_generator (MPlist *plist) -{ - FontLayoutStage *stage; - MPlist *elt, *pl; - FontLayoutCmd dummy; - - MSTRUCT_CALLOC (stage, MERROR_DRAW); - MLIST_INIT1 (stage, cmds, 32); - dummy.type = FontLayoutCmdTypeMAX; - MLIST_APPEND1 (stage, cmds, dummy, MERROR_FONT); - MPLIST_DO (elt, MPLIST_NEXT (plist)) - { - if (! MPLIST_PLIST_P (elt)) - MERROR (MERROR_FONT, NULL); - pl = MPLIST_PLIST (elt); - if (! MPLIST_SYMBOL_P (pl)) - MERROR (MERROR_FONT, NULL); - MLIST_APPEND1 (stage, cmds, dummy, MERROR_FONT); - } - - /* Load the first command from PLIST into STAGE->cmds[0]. Macros - called in the first command are also loaded from MPLIST_NEXT - (PLIST) into STAGE->cmds[n]. */ - if (load_command (stage, plist, MPLIST_NEXT (plist), INDEX_TO_CMD_ID (0)) - == INVALID_CMD_ID) - { - MLIST_FREE1 (stage, cmds); - free (stage); - MERROR (MERROR_DRAW, NULL); - } - - return stage; -} - - -/* Load FLT of name LAYOUTER_NAME from the m17n database into a newly - allocated memory, and return it. */ - -static MFontLayoutTable * -load_flt (MSymbol layouter_name) -{ - MDatabase *mdb; - MPlist *top = NULL, *plist; - MSymbol Mcategory = msymbol ("category"); - MSymbol Mgenerator = msymbol ("generator"); - MFontLayoutTable *layouter = NULL; - MCharTable *category = NULL; - - if (! (mdb = mdatabase_find (Mfont, Mlayouter, layouter_name, Mnil))) - MERROR_GOTO (MERROR_FONT, finish); - if (! (top = (MPlist *) mdatabase_load (mdb))) - MERROR_GOTO (0, finish); - if (! MPLIST_PLIST_P (top)) - MERROR_GOTO (MERROR_FONT, finish); - - MPLIST_DO (plist, top) - { - MSymbol sym; - MPlist *elt; - - if (! MPLIST_PLIST (plist)) - MERROR_GOTO (MERROR_FONT, finish); - elt = MPLIST_PLIST (plist); - if (! MPLIST_SYMBOL_P (elt)) - MERROR_GOTO (MERROR_FONT, finish); - sym = MPLIST_SYMBOL (elt); - elt = MPLIST_NEXT (elt); - if (! elt) - MERROR_GOTO (MERROR_FONT, finish); - if (sym == Mcategory) - { - if (category) - M17N_OBJECT_UNREF (category); - category = load_category_table (elt); - } - else if (sym == Mgenerator) - { - FontLayoutStage *stage; - - if (! category) - MERROR_GOTO (MERROR_FONT, finish); - stage = load_generator (elt); - if (! stage) - MERROR_GOTO (MERROR_FONT, finish); - stage->category = category; - M17N_OBJECT_REF (category); - if (! layouter) - { - layouter = mplist (); - /* Here don't do M17N_OBJECT_REF (category) because we - don't unref the value of the element added below. */ - mplist_add (layouter, Mcategory, category); - } - mplist_add (layouter, Mt, stage); - } - else - MERROR_GOTO (MERROR_FONT, finish); - } - - if (category) - M17N_OBJECT_UNREF (category); - - finish: - M17N_OBJECT_UNREF (top); - mplist_add (flt_list, layouter_name, layouter); - return layouter; -} - - -static void -free_flt_stage (FontLayoutStage *stage) -{ - int i; - - M17N_OBJECT_UNREF (stage->category); - for (i = 0; i < stage->used; i++) - free_flt_command (stage->cmds + i); - MLIST_FREE1 (stage, cmds); - free (stage); -} - - -static MFontLayoutTable * -get_font_layout_table (MSymbol layouter_name) -{ - MPlist *plist = mplist_find_by_key (flt_list, layouter_name); - - return (plist ? MPLIST_VAL (plist) : load_flt (layouter_name)); -} - - -/* FLS (Font Layout Service) */ - -/* Structure to hold information about a context of FLS. */ - -typedef struct -{ - /* Pointer to the current stage. */ - FontLayoutStage *stage; - - /* Encode each MGlyph->code by the current category table into this - array. An element is a category. */ - char *encoded; - /* [GIDX - ] gives a category for the glyph - index GIDX. */ - int encoded_offset; - int *match_indices; - int code_offset; - int cluster_begin_idx; - int cluster_begin_pos; - int cluster_end_pos; - int combining_code; - int left_padding; -} FontLayoutContext; - -static int run_command (int depth, - int, MGlyphString *, int, int, FontLayoutContext *); - -#define NMATCH 20 - -static int -run_rule (int depth, - FontLayoutCmdRule *rule, MGlyphString *gstring, int from, int to, - FontLayoutContext *ctx) -{ - int *saved_match_indices = ctx->match_indices; - int match_indices[NMATCH * 2]; - int consumed; - int i; - int orig_from = from; - - if (ctx->cluster_begin_idx) - { - if (ctx->cluster_begin_pos > MGLYPH (from)->pos) - ctx->cluster_begin_pos = MGLYPH (from)->pos; - if (ctx->cluster_end_pos < MGLYPH (to)->pos) - ctx->cluster_end_pos = MGLYPH (to)->pos; - } - - if (rule->src_type == SRC_SEQ) - { - int len; - - len = rule->src.seq.n_codes; - if (len > (to - from)) - return 0; - for (i = 0; i < len; i++) - if (rule->src.seq.codes[i] != gstring->glyphs[from + i].code) - break; - if (i < len) - return 0; - to = from + len; - MDEBUG_PRINT1 (" (SEQ 0x%X", rule->src.seq.codes[0]); - } - else if (rule->src_type == SRC_RANGE) - { - int head; - - if (from >= to) - return 0; - head = gstring->glyphs[from].code; - if (head < rule->src.range.from || head > rule->src.range.to) - return 0; - ctx->code_offset = head - rule->src.range.from; - to = from + 1; - MDEBUG_PRINT2 (" (RANGE 0x%X-0x%X", - rule->src.range.from, rule->src.range.to); - } - else if (rule->src_type == SRC_REGEX) - { - regmatch_t pmatch[NMATCH]; - char saved_code; - int result; - - if (from > to) - return 0; - saved_code = ctx->encoded[to - ctx->encoded_offset]; - ctx->encoded[to - ctx->encoded_offset] = '\0'; - result = regexec (&(rule->src.re.preg), - ctx->encoded + from - ctx->encoded_offset, - NMATCH, pmatch, 0); - if (result == 0 && pmatch[0].rm_so == 0) - { - MDEBUG_PRINT3 (" (REGEX \"%s\" \"%s\" %d", - rule->src.re.pattern, - ctx->encoded + from - ctx->encoded_offset, - pmatch[0].rm_eo); - ctx->encoded[to - ctx->encoded_offset] = saved_code; - for (i = 0; i < NMATCH; i++) - { - if (pmatch[i].rm_so < 0) - match_indices[i * 2] = match_indices[i * 2 + 1] = -1; - else - { - match_indices[i * 2] = from + pmatch[i].rm_so; - match_indices[i * 2 + 1] = from + pmatch[i].rm_eo; - } - } - ctx->match_indices = match_indices; - to = match_indices[1]; - } - else - { - ctx->encoded[to - ctx->encoded_offset] = saved_code; - return 0; - } - } - else if (rule->src_type == SRC_INDEX) - { - if (rule->src.match_idx >= NMATCH) - return 0; - from = ctx->match_indices[rule->src.match_idx * 2]; - if (from < 0) - return 0; - to = ctx->match_indices[rule->src.match_idx * 2 + 1]; - MDEBUG_PRINT1 (" (INDEX %d", rule->src.match_idx); - } - - consumed = 0; - depth++; - for (i = 0; i < rule->n_cmds; i++) - { - int pos; - - if (rule->cmd_ids[i] == CMD_ID_REPEAT) - { - if (! consumed) - continue; - i--; - } - pos = run_command (depth, rule->cmd_ids[i], gstring, from, to, ctx); - if (pos < 0) - MERROR (MERROR_DRAW, -1); - consumed = pos > from; - if (consumed) - from = pos; - } - - ctx->match_indices = saved_match_indices; - MDEBUG_PRINT (")"); - return (rule->src_type == SRC_INDEX ? orig_from : to); -} - -static int -run_cond (int depth, - FontLayoutCmdCond *cond, MGlyphString *gstring, int from, int to, - FontLayoutContext *ctx) -{ - int i, pos = 0; - - MDEBUG_PRINT2 ("\n [FLT] %*s(COND", depth, ""); - depth++; - for (i = 0; i < cond->n_cmds; i++) - if ((pos = run_command (depth, cond->cmd_ids[i], gstring, from, to, ctx)) - != 0) - break; - if (pos < 0) - MERROR (MERROR_DRAW, -1); - MDEBUG_PRINT (")"); - return (pos); -} - -static int -run_otf (int depth, - FontLayoutCmdOTF *otf_cmd, MGlyphString *gstring, int from, int to, - FontLayoutContext *ctx) -{ -#ifdef HAVE_OTF - int gidx = gstring->used; - - to = mfont__ft_drive_otf (gstring, from, to, - otf_cmd->script, otf_cmd->langsys, - otf_cmd->gsub_features, otf_cmd->gpos_features); - if (gidx < gstring->used) - MGLYPH (gidx)->left_padding = ctx->left_padding; -#endif - return to; -} - -static int -run_command (int depth, int id, MGlyphString *gstring, int from, int to, - FontLayoutContext *ctx) -{ - MGlyph g; - - if (id >= 0) - { - int i; - - /* Direct code (== id + ctx->code_offset) output. - The source is not consumed. */ - if (from < to) - g = *(MGLYPH (from)); - else - g = *(MGLYPH (from - 1)); - g.type = GLYPH_CHAR; - g.code = ctx->code_offset + id; - MDEBUG_PRINT1 (" (DIRECT 0x%X", g.code); - if (ctx->combining_code) - g.combining_code = ctx->combining_code; - if (ctx->left_padding) - g.left_padding = ctx->left_padding; - for (i = from; i < to; i++) - { - MGlyph *tmp = MGLYPH (i); - - if (g.pos > tmp->pos) - g.pos = tmp->pos; - else if (g.to < tmp->to) - g.to = tmp->to; - } - APPEND_GLYPH (gstring, g); - ctx->code_offset = ctx->combining_code = ctx->left_padding = 0; - MDEBUG_PRINT (")"); - return (from); - } - - if (id <= CMD_ID_OFFSET_INDEX) - { - int idx = CMD_ID_TO_INDEX (id); - FontLayoutCmd *cmd; - - if (idx >= ctx->stage->used) - MERROR (MERROR_DRAW, -1); - cmd = ctx->stage->cmds + idx; - if (cmd->type == FontLayoutCmdTypeRule) - to = run_rule (depth, &cmd->body.rule, gstring, from, to, ctx); - else if (cmd->type == FontLayoutCmdTypeCond) - to = run_cond (depth, &cmd->body.cond, gstring, from, to, ctx); - else if (cmd->type == FontLayoutCmdTypeOTF) - to = run_otf (depth, &cmd->body.otf, gstring, from, to, ctx); - - if (to < 0) - return -1; - return to; - } - - if (id <= CMD_ID_OFFSET_COMBINING) - { - ctx->combining_code = CMD_ID_TO_COMBINING_CODE (id); - return from; - } - - switch (id) - { - case CMD_ID_COPY: - { - if (from >= to) - return from; - g = *(MGLYPH (from)); - if (ctx->combining_code) - g.combining_code = ctx->combining_code; - if (ctx->left_padding) - g.left_padding = ctx->left_padding; - APPEND_GLYPH (gstring, g); - ctx->code_offset = ctx->combining_code = ctx->left_padding = 0; - return (from + 1); - } - - case CMD_ID_CLUSTER_BEGIN: - if (! ctx->cluster_begin_idx) - { - MDEBUG_PRINT1 (" <%d", MGLYPH (from)->pos); - ctx->cluster_begin_idx = gstring->used; - ctx->cluster_begin_pos = MGLYPH (from)->pos; - ctx->cluster_end_pos = MGLYPH (from)->to; - } - return from; - - case CMD_ID_CLUSTER_END: - if (ctx->cluster_begin_idx && ctx->cluster_begin_idx < gstring->used) - { - int i; - - MDEBUG_PRINT1 (" %d>", ctx->cluster_end_pos); - for (i = ctx->cluster_begin_idx; i < gstring->used; i++) - { - MGLYPH (i)->pos = ctx->cluster_begin_pos; - MGLYPH (i)->to = ctx->cluster_end_pos; - } - ctx->cluster_begin_idx = 0; - } - return from; - - case CMD_ID_SEPARATOR: - { - if (from < to) - g = *(MGLYPH (from)); - else - g = *(MGLYPH (from - 1)); - g.type = GLYPH_PAD; - /* g.c = g.code = 0; */ - g.width = 0; - APPEND_GLYPH (gstring, g); - return from; - } - - case CMD_ID_LEFT_PADDING: - ctx->left_padding = 1; - return from; - - case CMD_ID_RIGHT_PADDING: - if (gstring->used > 0) - gstring->glyphs[gstring->used - 1].right_padding = 1; - return from; - } - - MERROR (MERROR_DRAW, -1); -} - - -/* Internal API */ - -int -mfont__flt_init (void) -{ - Mcond = msymbol ("cond"); - Mrange = msymbol ("range"); - Mlayouter = msymbol ("layouter"); - flt_list = mplist (); - return 0; -} - -void -mfont__flt_fini (void) -{ - MPlist *plist, *pl; - - MPLIST_DO (plist, flt_list) - { - pl = MPLIST_PLIST (plist); - if (pl) - { - MPLIST_DO (pl, MPLIST_NEXT (pl)) - free_flt_stage (MPLIST_VAL (pl)); - pl = MPLIST_PLIST (plist); - M17N_OBJECT_UNREF (pl); - } - } - M17N_OBJECT_UNREF (flt_list); -} - -unsigned -mfont__flt_encode_char (MSymbol layouter_name, int c) -{ - MFontLayoutTable *layouter = get_font_layout_table (layouter_name); - MCharTable *table; - unsigned code; - - if (! layouter) - return MCHAR_INVALID_CODE; - table = MPLIST_VAL (layouter); - code = (unsigned) mchartable_lookup (table, c); - return (code ? code : MCHAR_INVALID_CODE); -} - -int -mfont__flt_run (MGlyphString *gstring, int from, int to, - MSymbol layouter_name, MRealizedFace *ascii_rface) -{ - int stage_idx = 0; - int gidx; - int i; - FontLayoutContext ctx; - MCharTable *table; - int encoded_len; - int match_indices[NMATCH]; - MFontLayoutTable *layouter = get_font_layout_table (layouter_name); - FontLayoutStage *stage; - int from_pos, to_pos; - MGlyph dummy; - - if (! layouter) - { - /* FLT not found. Make all glyphs invisible. */ - while (from < to) - gstring->glyphs[from++].code = MCHAR_INVALID_CODE; - return to; - } - - dummy = gstring->glyphs[from]; - MDEBUG_PRINT1 (" [FLT] (%s", msymbol_name (layouter_name)); - - /* Setup CTX. */ - memset (&ctx, 0, sizeof ctx); - table = MPLIST_VAL (layouter); - layouter = MPLIST_NEXT (layouter); - stage = (FontLayoutStage *) MPLIST_VAL (layouter); - gidx = from; - /* Find previous glyphs that are also supported by the layouter. */ - while (gidx > 1 - && mchartable_lookup (table, MGLYPH (gidx - 1)->c)) - gidx--; - /* + 2 is for a separator ' ' and a terminator '\0'. */ - encoded_len = gstring->used - gidx + 2; - ctx.encoded = (char *) alloca (encoded_len); - - for (i = 0; gidx < from; i++, gidx++) - ctx.encoded[i] = (int) mchartable_lookup (table, MGLYPH (gidx)->c); - - ctx.encoded[i++] = ' '; - ctx.encoded_offset = from - i; - - /* Now each MGlyph->code contains encoded char. Set it in - ctx.encoded[], and set MGlyph->c to MGlyph->code. */ - for (gidx = from; gidx < to ; i++, gidx++) - { - ctx.encoded[i] = (int) MGLYPH (gidx)->code; - MGLYPH (gidx)->code = (unsigned) MGLYPH (gidx)->c; - } - ctx.encoded[i++] = '\0'; - - match_indices[0] = from; - match_indices[1] = to; - for (i = 2; i < NMATCH; i++) - match_indices[i] = -1; - ctx.match_indices = match_indices; - - from_pos = MGLYPH (from)->pos; - to_pos = MGLYPH (to)->pos; - - for (stage_idx = 0; 1; stage_idx++) - { - int len = to - from; - int result; - - MDEBUG_PRINT1 ("\n [FLT] (STAGE %d", stage_idx); - gidx = gstring->used; - ctx.stage = stage; - - result = run_command (2, INDEX_TO_CMD_ID (0), gstring, - ctx.encoded_offset, to, &ctx); - MDEBUG_PRINT (")"); - if (result < 0) - return -1; - to = from + (gstring->used - gidx); - REPLACE_GLYPHS (gstring, gidx, from, len); - - layouter = MPLIST_NEXT (layouter); - /* If this is the last stage, break the loop. */ - if (MPLIST_TAIL_P (layouter)) - break; - - /* Otherwise, prepare for the next iteration. */ - stage = (FontLayoutStage *) MPLIST_VAL (layouter); - table = stage->category; - if (to - from >= encoded_len) - { - encoded_len = to + 1; - ctx.encoded = (char *) alloca (encoded_len); - } - - for (i = from; i < to; i++) - { - MGlyph *g = MGLYPH (i); - - if (g->type == GLYPH_PAD) - ctx.encoded[i - from] = ' '; - else if (! g->otf_encoded) - ctx.encoded[i - from] = (int) mchartable_lookup (table, g->code); -#ifdef HAVE_FREETYPE - else - { - int c = mfont__ft_decode_otf (g); - - if (c >= 0) - { - c = (int) mchartable_lookup (table, c); - if (! c) - c = -1; - } - ctx.encoded[i - from] = (c >= 0 ? c : 1); - } -#endif /* HAVE_FREETYPE */ - } - ctx.encoded[i - from] = '\0'; - ctx.encoded_offset = from; - ctx.match_indices[0] = from; - ctx.match_indices[1] = to; - } - - MDEBUG_PRINT (")\n"); - - if (from == to) - { - /* Somehow there's no glyph contributing to characters between - FROM_POS and TO_POS. We must add one dummy space glyph for - those characters. */ - MGlyph g; - - g.type = GLYPH_SPACE; - g.c = ' ', g.code = ' '; - g.pos = from_pos, g.to = to_pos; - g.rface = ascii_rface; - INSERT_GLYPH (gstring, from, g); - to = from + 1; - } - else - { - /* Here we must check if all characters in the range is covered - by some glyph(s). If not, change and of glyphs to - cover uncovered characters. */ - int len = to_pos - from_pos; - int pos; - MGlyph **glyphs = alloca (sizeof (MGlyph) * len); - MGlyph *g, *gend = MGLYPH (to); - MGlyph *latest = gend; - - for (i = 0; i < len; i++) - glyphs[i] = NULL; - for (g = MGLYPH (from); g != gend; g++) - { - if (g->pos < latest->pos) - latest = g; - if (! glyphs[g->pos - from_pos]) - { - for (i = g->pos; i < g->to; i++) - glyphs[i - from_pos] = g; - } - } - i = 0; - if (! glyphs[0]) - { - pos = latest->pos; - for (g = latest; g->pos == pos; g++) - g->pos = from_pos; - i++; - } - for (; i < len; i++) - { - if (! glyphs[i]) - { - for (g = latest; g->pos == latest->pos; g++) - g->to = from_pos + i + 1; - } - else - latest = glyphs[i]; - } - } - return to; -} - - -/* for debugging... */ - -static void -dump_flt_cmd (FontLayoutStage *stage, int id, int indent) -{ - char *prefix = (char *) alloca (indent + 1); - - memset (prefix, 32, indent); - prefix[indent] = 0; - - if (id >= 0) - fprintf (stderr, "0x%02X", id); - else if (id <= CMD_ID_OFFSET_INDEX) - { - int idx = CMD_ID_TO_INDEX (id); - FontLayoutCmd *cmd = stage->cmds + idx; - - if (cmd->type == FontLayoutCmdTypeRule) - { - FontLayoutCmdRule *rule = &cmd->body.rule; - int i; - - fprintf (stderr, "(rule "); - if (rule->src_type == SRC_REGEX) - fprintf (stderr, "\"%s\"", rule->src.re.pattern); - else if (rule->src_type == SRC_INDEX) - fprintf (stderr, "%d", rule->src.match_idx); - else if (rule->src_type == SRC_SEQ) - fprintf (stderr, "(seq)"); - else if (rule->src_type == SRC_RANGE) - fprintf (stderr, "(range)"); - else - fprintf (stderr, "(invalid src)"); - - for (i = 0; i < rule->n_cmds; i++) - { - fprintf (stderr, "\n%s ", prefix); - dump_flt_cmd (stage, rule->cmd_ids[i], indent + 2); - } - fprintf (stderr, ")"); - } - else if (cmd->type == FontLayoutCmdTypeCond) - { - FontLayoutCmdCond *cond = &cmd->body.cond; - int i; - - fprintf (stderr, "(cond"); - for (i = 0; i < cond->n_cmds; i++) - { - fprintf (stderr, "\n%s ", prefix); - dump_flt_cmd (stage, cond->cmd_ids[i], indent + 2); - } - fprintf (stderr, ")"); - } - else if (cmd->type == FontLayoutCmdTypeOTF) - { - fprintf (stderr, "(otf)"); - } - else - fprintf (stderr, "(error-command)"); - } - else if (id <= CMD_ID_OFFSET_COMBINING) - fprintf (stderr, "cominging-code"); - else - fprintf (stderr, "(predefiend %d)", id); -} - -void -dump_flt (MFontLayoutTable *flt, int indent) -{ - char *prefix = (char *) alloca (indent + 1); - MPlist *plist; - int stage_idx = 0; - - memset (prefix, 32, indent); - prefix[indent] = 0; - fprintf (stderr, "(flt"); - MPLIST_DO (plist, flt) - { - FontLayoutStage *stage = (FontLayoutStage *) MPLIST_VAL (plist); - int i; - - fprintf (stderr, "\n%s (stage %d", prefix, stage_idx); - for (i = 0; i < stage->used; i++) - { - fprintf (stderr, "\n%s ", prefix); - dump_flt_cmd (stage, INDEX_TO_CMD_ID (i), indent + 4); - } - fprintf (stderr, ")"); - stage_idx++; - } - fprintf (stderr, ")"); -} diff --git a/src/fontset.h b/src/fontset.h deleted file mode 100644 index 872650a..0000000 --- a/src/fontset.h +++ /dev/null @@ -1,37 +0,0 @@ -/* fontset.h -- header file for the fontset module. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -#ifndef _M17N_FONTSET_H_ -#define _M17N_FONTSET_H_ - -extern MRealizedFontset *mfont__realize_fontset (MFrame *frame, - MFontset *fontset, - MFace *face); - -void mfont__free_realized_fontset (MRealizedFontset *realized); - -extern MRealizedFont *mfont__lookup_fontset (MRealizedFontset *realized, - MGlyph *g, int *num, - MSymbol script, MSymbol language, - MSymbol charset, int size); - -#endif /* _M17N_FONTSET_H_ */ diff --git a/src/input-gui.c b/src/input-gui.c deleted file mode 100644 index f9b3144..0000000 --- a/src/input-gui.c +++ /dev/null @@ -1,730 +0,0 @@ -/* input-gui.c -- gui-based input method module. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -/***en - @addtogroup m17nInputMethodWin - @brief Input method support on window systems. - - The input driver @c minput_gui_driver is provided for internal - input methods that is useful on window systems. It displays - preedit text and status text at the inputting spot. See the - documentation of @c minput_gui_driver for more detail. - - In the m17n-X library, the foreign input method of name @c Mxim is - provided. It uses XIM (X Input Method) as a background input - engine. The symbol @c Mxim has a property @c Minput_driver whose - value is a pointer to the input driver @c minput_xim_driver. See - the documentation of @c minput_xim_driver for more detail. */ - -/***ja - @addtogroup m17nInputMethodWin - @brief ¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥à¾å¤ÎÆþÎϥ᥽¥Ã¥É¤Î¥µ¥Ý¡¼¥È - - ÆþÎϥɥ饤¥Ð @c minput_gui_driver ¤Ï¡¢¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥à¾å¤ÇÊØÍø¤Ë - ÍѤ¤¤é¤ì¤ëÆâÉôÆþÎϥ᥽¥Ã¥É¤Î¤¿¤á¤Î¤â¤Î¤Ç¤¢¤ë¡£¤³¤Î¥É¥é¥¤¥Ð¤ÏÆþÎÏ¥¹ - ¥Ý¥Ã¥È¤Ë preedit ¥Æ¥­¥¹¥È¤È status ¥Æ¥­¥¹¥È¤òɽ¼¨¤¹¤ë¡£¾ÜºÙ¤Ë¤Ä¤¤ - ¤Æ¤Ï @c minput_gui_driver ¤Î¥É¥­¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£ - - m17n-X ¥é¥¤¥Ö¥é¥ê¤Ï¡¢@c Mxim ¤È¸À¤¦Ì¾Á°¤ò»ý¤Ä³°ÉôÆþÎϥ᥽¥Ã¥É¤òÄó - ¶¡¤·¤Æ¤¤¤ë¡£¤³¤ì¤Ï XIM (X Input Method) ¤ò¥Ð¥Ã¥¯¥°¥é¥¦¥ó¥É¤ÎÆþÎÏ¥¨ - ¥ó¥¸¥ó¤È¤·¤ÆÍøÍѤ¹¤ë¡£¥·¥ó¥Ü¥ë @c Mxim ¤Ï @c Minput_driver ¤È¤¤¤¦ - ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ã¤Æ¤ª¤ê¡¢¤½¤ÎÃͤÏÆþÎϥɥ饤¥Ð @c minput_xim_driver - ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£ ¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï @c minput_xim_driver ¤Î¥É¥­¥å - ¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£ */ - -/*=*/ - -#if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE) -/*** @addtogroup m17nInternal - @{ */ - -#include -#include - -#include "m17n-gui.h" -#include "m17n-misc.h" -#include "internal.h" -#include "internal-gui.h" -#include "input.h" - -typedef struct -{ - MDrawWindow win; - MDrawMetric geometry; - MDrawControl control; - int mapped; -} MInputGUIWinInfo; - -typedef struct -{ - MInputContextInfo *ic_info; - - MFrame *frame; - /* .x and .y are not used. */ - MInputGUIWinInfo client; - /* In the following members, is relative to . */ - MInputGUIWinInfo focus; - MInputGUIWinInfo preedit; - MInputGUIWinInfo status; - MInputGUIWinInfo candidates; -} MInputGUIContextInfo; - -static MFace *status_face; -static MFaceBoxProp face_box_prop; - -static int -win_create_ic (MInputContext *ic) -{ - MInputGUIContextInfo *win_ic_info; - MInputGUIArgIC *win_info = (MInputGUIArgIC *) ic->arg; - MFrame *frame = win_info->frame; - - if ((*minput_default_driver.create_ic) (ic) < 0) - return -1; - - MSTRUCT_CALLOC (win_ic_info, MERROR_IM); - win_ic_info->ic_info = (MInputContextInfo *) ic->info; - win_ic_info->frame = frame; - win_ic_info->client.win = win_info->client; - mwin__window_geometry (frame, win_info->client, win_info->client, - &win_ic_info->client.geometry); - win_ic_info->focus.win = win_info->focus; - mwin__window_geometry (frame, win_info->focus, win_info->client, - &win_ic_info->focus.geometry); - - win_ic_info->preedit.win = mwin__create_window (frame, win_info->client); - win_ic_info->preedit.control.two_dimensional = 1; - win_ic_info->preedit.control.as_image = 1; - win_ic_info->preedit.control.with_cursor = 1; - win_ic_info->preedit.control.cursor_width = 1; - win_ic_info->preedit.control.disable_caching = 1; - win_ic_info->preedit.geometry.x = -1; - win_ic_info->preedit.geometry.y = -1; - - win_ic_info->status.win = mwin__create_window (frame, win_info->client); - win_ic_info->status.control.as_image = 1; - - win_ic_info->candidates.win = mwin__create_window (frame, win_info->client); - win_ic_info->candidates.control.as_image = 1; - - ic->info = win_ic_info; - - return 0; -} - -static void -win_destroy_ic (MInputContext *ic) -{ - MInputGUIContextInfo *win_ic_info = (MInputGUIContextInfo *) ic->info; - MInputContextInfo *ic_info = (MInputContextInfo *) win_ic_info->ic_info; - - mwin__destroy_window (win_ic_info->frame, win_ic_info->preedit.win); - mwin__destroy_window (win_ic_info->frame, win_ic_info->status.win); - mwin__destroy_window (win_ic_info->frame, win_ic_info->candidates.win); - ic->info = ic_info; - (*minput_default_driver.destroy_ic) (ic); - free (win_ic_info); -} - -static int -win_filter (MInputContext *ic, MSymbol key, void *arg) -{ - MInputGUIContextInfo *win_ic_info = (MInputGUIContextInfo *) ic->info; - MInputContextInfo *ic_info = (MInputContextInfo *) win_ic_info->ic_info; - int ret; - - if (! ic - || ! ic->active) - return 0; - - if (key == Mnil) - { - if (! arg) - return 0; - key = minput_event_to_key (win_ic_info->frame, arg); - if (key == Mnil) - return 1; - } - ic->info = ic_info; - ret = (*minput_default_driver.filter) (ic, key, arg); - ic->info = win_ic_info; - return ret; -} - -static void -adjust_window_and_draw (MFrame *frame, MInputContext *ic, MText *mt, int type) -{ - MInputGUIContextInfo *win_ic_info = (MInputGUIContextInfo *) ic->info; - MDrawControl *control; - MDrawWindow win; - MDrawMetric *geometry, physical, logical; - int xoff = win_ic_info->focus.geometry.x; - int yoff = win_ic_info->focus.geometry.y; - int x0, x1, y0, y1; - int len = mtext_nchars (mt); - - if (type == 0) - { - win = win_ic_info->preedit.win; - control = &win_ic_info->preedit.control; - geometry = &win_ic_info->preedit.geometry; - len++; - } - else if (type == 1) - { - win = win_ic_info->status.win; - control = &win_ic_info->status.control; - geometry = &win_ic_info->status.geometry; - } - else - { - win = win_ic_info->candidates.win; - control = &win_ic_info->candidates.control; - geometry = &win_ic_info->candidates.geometry; - } - - mdraw_text_extents (frame, mt, 0, len, control, &physical, &logical, NULL); - x0 = physical.x, x1 = x0 + physical.width; - y0 = physical.y, y1 = y0 + physical.height; - if (x0 > logical.x) - x0 = logical.x; - if (x1 < logical.x + logical.width) - x1 = logical.x + logical.width; - if (y0 > logical.y) - y0 = logical.y; - if (y1 < logical.y + logical.height) - y1 = logical.y + logical.height; - physical.width = x1 - x0; - physical.height = y1 - y0; - physical.x = xoff + ic->spot.x; - if (physical.x + physical.width > win_ic_info->client.geometry.width) - physical.x = win_ic_info->client.geometry.width - physical.width; - if (type == 0) - { - if (y0 > - ic->spot.ascent) - { - physical.height += y0 + ic->spot.ascent; - y0 = - ic->spot.ascent; - } - if (y1 < ic->spot.descent) - { - physical.height += ic->spot.descent - y1; - } - physical.y = yoff + ic->spot.y + y0; - } - else if (type == 1) - { - physical.y = yoff + ic->spot.y + ic->spot.descent + 2; - if (physical.y + physical.height > win_ic_info->client.geometry.height - && yoff + ic->spot.y - ic->spot.ascent - 2 - physical.height >= 0) - physical.y = yoff + ic->spot.y - ic->spot.ascent - 2 - physical.height; - } - else - { - if (win_ic_info->status.mapped) - { - /* We assume that status is already drawn. */ - if (win_ic_info->status.geometry.y < yoff + ic->spot.y) - /* As there was no lower room for status, candidates must also - be drawn upper. */ - physical.y = win_ic_info->status.geometry.y - 1 - physical.height; - else - { - /* There was a lower room for status. */ - physical.y = (win_ic_info->status.geometry.y - + win_ic_info->status.geometry.height - + 1); - if (physical.y + physical.height - > win_ic_info->client.geometry.height) - /* But not for candidates. */ - physical.y = (yoff + ic->spot.y - ic->spot.ascent - 1 - - physical.height); - } - } - else - { - physical.y = yoff + ic->spot.y + ic->spot.descent + 2; - if ((physical.y + physical.height - > win_ic_info->client.geometry.height) - && (yoff + ic->spot.y - ic->spot.ascent - 2 - physical.height - >= 0)) - physical.y = (yoff + ic->spot.y - ic->spot.ascent - 2 - - physical.height); - } - } - - mwin__adjust_window (frame, win, geometry, &physical); - mdraw_text_with_control (frame, win, -x0, -y0, mt, 0, len, control); -} - -static void -win_callback (MInputContext *ic, MSymbol command) -{ - MInputGUIContextInfo *win_ic_info = (MInputGUIContextInfo *) ic->info; - MFrame *frame = win_ic_info->frame; - - if (command == Minput_preedit_draw) - { - MText *mt; - MFace *face = mface (); - - if (! win_ic_info->preedit.mapped) - { - mwin__map_window (frame, win_ic_info->preedit.win); - win_ic_info->preedit.mapped = 1; - } - win_ic_info->preedit.control.cursor_pos = ic->cursor_pos; - if (ic->spot.fontsize) - mface_put_prop (face, Msize, (void *) ic->spot.fontsize); - mface_merge (face, mface_underline); - mtext_push_prop (ic->preedit, 0, mtext_nchars (ic->preedit), - Mface, face); - M17N_OBJECT_UNREF (face); - if (ic->im->language != Mnil) - mtext_put_prop (ic->preedit, 0, mtext_nchars (ic->preedit), Mlanguage, - ic->im->language); - if (ic->candidate_list) - mtext_push_prop (ic->preedit, ic->candidate_from, ic->candidate_to, - Mface, mface_reverse_video); - if (mtext_nchars (ic->produced) == 0) - mt = ic->preedit; - else - { - mt = mtext_dup (ic->produced); - mtext_cat (mt, ic->preedit); - win_ic_info->preedit.control.cursor_pos - += mtext_nchars (ic->produced); - } - adjust_window_and_draw (frame, ic, mt, 0); - if (ic->candidate_list) - mtext_pop_prop (ic->preedit, 0, mtext_nchars (ic->preedit), Mface); - mtext_pop_prop (ic->preedit, 0, mtext_nchars (ic->preedit), Mface); - if (mtext_nchars (ic->produced) != 0) - M17N_OBJECT_UNREF (mt); - } - else if (command == Minput_status_draw) - { - if (! win_ic_info->client.win) - return; - mtext_put_prop (ic->status, 0, mtext_nchars (ic->status), Mface, - status_face); - if (ic->im->language != Mnil) - mtext_put_prop (ic->status, 0, mtext_nchars (ic->status), Mlanguage, - ic->im->language); - adjust_window_and_draw (frame, ic, ic->status, 1); - } - else if (command == Minput_candidates_draw) - { - MPlist *group; - MText *mt; - int i, len; - int from, to; - - if (! ic->candidate_list || ! ic->candidate_show) - { - if (win_ic_info->candidates.mapped) - { - mwin__unmap_window (frame, win_ic_info->candidates.win); - win_ic_info->candidates.mapped = 0; - } - return; - } - - if (! win_ic_info->candidates.mapped) - { - mwin__map_window (frame, win_ic_info->candidates.win); - win_ic_info->candidates.mapped = 1; - } - - i = 0; - group = ic->candidate_list; - while (1) - { - if (mplist_key (group) == Mtext) - len = mtext_len (mplist_value (group)); - else - len = mplist_length (mplist_value (group)); - if (i + len > ic->candidate_index) - break; - i += len; - group = mplist_next (group); - } - - mt = mtext (); - if (mplist_key (group) == Mtext) - { - MText *candidates = (MText *) mplist_value (group); - - from = (ic->candidate_index - i) * 2 + 1; - to = from + 1; - for (i = 0; i < len; i++) - { - mtext_cat_char (mt, ' '); - mtext_cat_char (mt, mtext_ref_char (candidates, i)); - } - } - else - { - MPlist *pl; - - for (pl = (MPlist *) mplist_value (group); - i < ic->candidate_index && mplist_key (pl) != Mnil; - i++, pl = mplist_next (pl)) - { - mtext_cat_char (mt, ' '); - mtext_cat (mt, (MText *) mplist_value (pl)); - } - from = mtext_nchars (mt) + 1; - to = from + mtext_nchars ((MText *) mplist_value (pl)); - for (; mplist_key (pl) != Mnil; pl = mplist_next (pl)) - { - mtext_cat_char (mt, ' '); - mtext_cat (mt, (MText *) mplist_value (pl)); - } - } - mtext_cat_char (mt, ' '); - mtext_push_prop (mt, 0, mtext_nchars (mt), Mface, status_face); - mtext_push_prop (mt, from, to, Mface, mface_reverse_video); - if (ic->im->language != Mnil) - mtext_put_prop (mt, 0, mtext_nchars (mt), Mlanguage, ic->im->language); - adjust_window_and_draw (frame, ic, mt, 2); - M17N_OBJECT_UNREF (mt); - } - else if (command == Minput_set_spot) - { - minput__callback (ic, Minput_preedit_draw); - minput__callback (ic, Minput_status_draw); - minput__callback (ic, Minput_candidates_draw); - } - else if (command == Minput_toggle) - { - if (ic->active) - { - minput__callback (ic, Minput_preedit_done); - minput__callback (ic, Minput_status_done); - minput__callback (ic, Minput_candidates_done); - } - else - { - minput__callback (ic, Minput_preedit_start); - minput__callback (ic, Minput_status_start); - minput__callback (ic, Minput_candidates_start); - } - } - else if (command == Minput_preedit_start) - { - } - else if (command == Minput_preedit_done) - { - if (win_ic_info->preedit.mapped) - { - mwin__unmap_window (frame, win_ic_info->preedit.win); - win_ic_info->preedit.mapped = 0; - } - } - else if (command == Minput_status_start) - { - if (! win_ic_info->status.mapped) - { - mwin__map_window (frame, win_ic_info->status.win); - win_ic_info->status.mapped = 1; - } - } - else if (command == Minput_status_done) - { - if (win_ic_info->status.mapped) - { - mwin__unmap_window (frame, win_ic_info->status.win); - win_ic_info->status.mapped = 0; - } - } - else if (command == Minput_candidates_start) - { - if (! win_ic_info->candidates.mapped) - { - mwin__map_window (frame, win_ic_info->candidates.win); - win_ic_info->candidates.mapped = 1; - } - } - else if (command == Minput_candidates_done) - { - if (win_ic_info->candidates.mapped) - { - mwin__unmap_window (frame, win_ic_info->candidates.win); - win_ic_info->candidates.mapped = 0; - } - } -} - -static int -win_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt) -{ - MInputGUIContextInfo *win_ic_info = (MInputGUIContextInfo *) ic->info; - MInputContextInfo *ic_info = (MInputContextInfo *) win_ic_info->ic_info; - int ret; - - ic->info = ic_info; - ret = (*minput_default_driver.lookup) (ic, key, arg, mt); - ic->info = win_ic_info; - return ret; -} - - - -int -minput__win_init () -{ - minput_gui_driver = minput_default_driver; - - minput_gui_driver.create_ic = win_create_ic; - minput_gui_driver.destroy_ic = win_destroy_ic; - minput_gui_driver.filter = win_filter; - minput_gui_driver.lookup = win_lookup; - { - MPlist *plist = mplist (); - - minput_gui_driver.callback_list = plist; - plist = mplist_add (plist, Minput_preedit_start, (void *) win_callback); - plist = mplist_add (plist, Minput_preedit_draw, (void *) win_callback); - plist = mplist_add (plist, Minput_preedit_done, (void *) win_callback); - plist = mplist_add (plist, Minput_status_start, (void *) win_callback); - plist = mplist_add (plist, Minput_status_draw, (void *) win_callback); - plist = mplist_add (plist, Minput_status_done, (void *) win_callback); - plist = mplist_add (plist, Minput_candidates_start, (void *) win_callback); - plist = mplist_add (plist, Minput_candidates_draw, (void *) win_callback); - plist = mplist_add (plist, Minput_candidates_done, (void *) win_callback); - plist = mplist_add (plist, Minput_set_spot, (void *) win_callback); - plist = mplist_add (plist, Minput_toggle, (void *) win_callback); - } - minput_driver = &minput_gui_driver; - - face_box_prop.width = 1; - face_box_prop.color_top = face_box_prop.color_left - = face_box_prop.color_bottom = face_box_prop.color_right - = msymbol ("black"); - face_box_prop.inner_hmargin = face_box_prop.inner_vmargin = 2; - face_box_prop.outer_hmargin = face_box_prop.outer_vmargin = 1; - status_face = mface (); - mface_put_prop (status_face, Mbox, &face_box_prop); - - return 0; -} - -void -minput__win_fini () -{ - M17N_OBJECT_UNREF (status_face); - if (minput_gui_driver.callback_list) - { - M17N_OBJECT_UNREF (minput_gui_driver.callback_list); - minput_gui_driver.callback_list = NULL; - } -} - -/*** @} */ -#endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */ - - -/* External API */ - -/*** @addtogroup m17nInputMethodWin */ -/*** @{ */ - -/*=*/ -/***en - @brief Input driver for internal input methods on window systems. - - The input driver @c minput_gui_driver is for internal input - methods to be used on window systems. - - It creates sub-windows for a preedit text and a status text, and - displays them at the input spot set by the function - minput_set_spot (). - - The function m17n_initialize_win () set the variable @c - minput_driver to the pointer to this driver so that all internal - input methods use it. - - Therefore, unless @c minput_driver is changed from the default, - the driver dependent arguments to the functions whose name begin - with minput_ must are treated as follows. - - The argument $ARG of the function minput_open_im () is ignored. - - The argument $ARG of the function minput_create_ic () must be a - pointer to the structure @c MInputGUIArgIC. See the documentation - of @c MInputGUIArgIC for more detail. - - If the argument $KEY is @c Mnil, the argument $ARG of the - function minput_filter () must be a pointer to the object of type - @c XEvent. In that case, $KEY is generated from $ARG. - - The argument $ARG of the function minput_lookup () must be the - same one as that of the function minput_filter (). */ - -/***ja - @brief ¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥à¤ÎÆâÉôÆþÎϥ᥽¥Ã¥ÉÍÑÆþÎϥɥ饤¥Ð - - ÆþÎϥɥ饤¥Ð @c minput_gui_driver ¤Ï¡¢¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥à¾å¤ÇÍѤ¤¤é - ¤ì¤ëÆþÎϥ᥽¥Ã¥ÉÍѤΤâ¤Î¤Ç¤¢¤ë¡£ - - ¤³¤Î¥É¥é¥¤¥Ð¤Ï¡¢´Ø¿ô minput_set_spot () ¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤¿ÆþÎÏ¥¹¥Ý¥Ã - ¥È¤Ë preedit ¥Æ¥­¥¹¥ÈÍѤΥµ¥Ö¥¦¥£¥ó¥É¥¦¤È status ¥Æ¥­¥¹¥ÈÍѤΥµ¥Ö - ¥¦¥£¥ó¥É¥¦¤òºî¤ê¡¢¤½¤ì¤¾¤ì¤òɽ¼¨¤¹¤ë¡£ - - ´Ø¿ô m17n_initialize_win () ¤ÏÊÑ¿ô @c minput_driver ¤ò¤³¤Î¥É¥é¥¤¥Ð - ¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è - ¤¦¤Ë¤¹¤ë¡£ - - ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_ - ¤Ç»Ï¤Þ¤ë̾Á°¤ò»ý¤Ä°Ê²¼¤Î´Ø¿ô·²¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô¤Ï¼¡¤Î¤è¤¦¤Ë - ¤Ê¤ë¡£ - - ´Ø¿ô minput_open_im () ¤Î°ú¿ô $ARG ¤Ï̵»ë¤µ¤ì¤ë¡£ - - ´Ø¿ô minput_create_ic () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ @c MInputGUIArgIC ¤Ø - ¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï @c MInputGUIArgIC ¤Î - ¥É¥­¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£ - - ´Ø¿ô minput_filter () ¤Î°ú¿ô $ARG ¤¬ @c Mnil ¤Î¾ì¹ç¡¢ $ARG ¤Ï - XEvent ·¿¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤³¤Î¾ì¹ç $KEY - ¤Ï $ARG ¤«¤éÀ¸À®¤µ¤ì¤ë¡£ - - ´Ø¿ô minput_lookup () ¤Î°ú¿ô $ARG ¤Ï´Ø¿ô minput_filter () °ú¿ô - $ARG ¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */ - -MInputDriver minput_gui_driver; - -/*=*/ - -/***en - @brief Convert an event to an input key. - - The minput_event_to_key () function returns the input key - corresponding to event $EVENT on $FRAME by a window system - dependent manner. - - In the m17n-X library, $EVENT must be a pointer to the struct @c - XKeyEvent, and it is handled as below. - - At first, the keysym name of $EVENT is acquired by the function @c - XKeysymToString. - - Then, the name is modified as below. - - If the name is one of "a" .. "z" and $EVENT has a Shift modifier, - the name is converted to "A" .. "Z" respectively, and the Shift - modifier is cleared. - - If the name is one byte length and $EVENT has a Control modifier, - the byte is bitwise anded by 0x1F and the Control modifier is - cleared. - - If $EVENT still has Shift, Control, Meta, Alt, Super, and/or Hyper - modifiers, the name is prepended by "S-", "C-", "M-", "A-", "s-", - and/or "H-" respectively in this order. - - For instance, if the keysym name is "a" and the event has Shift, - Meta, and Hyper modifiers, the resulting name is "H-M-A". - - At last, a symbol who has the name is returned. */ - -/***ja - @brief ¥­¡¼Ì¾¾Î¤òÆþÎÏ¥­¡¼¤ËÊÑ´¹¤¹¤ë - - ´Ø¿ô minput_name_to_key () ¤Ï¡¢Ì¾Á° $NAME ¤ËÂбþ¤¹¤ëÆþÎÏ¥­¡¼¤òÊÖ¤¹¡£ - - $NAME ¤Ï¼¡¤Î·Á¤ò¤È¤ë¡£ - - [ MODIFIER-MNEMONIC '-' ] * KEY-NAME - - ¤³¤³¤Ç MODIFIER-MNEMONIC ¤Ï 'S', 'C', 'M', 'A', 's', 'H' ¤Î¤¤¤º¤ì - ¤«¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì Shift, Control, Meta, Alt, Super, Hyper ¤Î³Æ¥â - ¥Ç¥£¥Õ¥¡¥¤¥¢¤ò¼¨¤¹¡£KEY-NAME ¤ÏÆþÎÏ¥­¡¼¤Î¥·¥ó¥Ü¥ê¥Ã¥¯¤Ê̾Á°¤òɽ¤¹Ê¸»úÎó¡£ - - ÆþÎÏ¥­¡¼¤Î²¼ 16 ¥Ó¥Ã¥È¤Ï "keysym bits" ¤È¤è¤Ð¤ì¡¢KEY-NAME ¤ËÂбþ¤¹ - ¤ë¥³¡¼¥É¤òɽ¤¹¡£¾å7 bits (¤Ä¤Þ¤ê 17 ¥Ó¥Ã¥ÈÌܤ«¤é 23 ¥Ó¥Ã¥ÈÌܤޤÇ) - ¤Ï"modifier bits" ¤È¸Æ¤Ð¤ì¡¢MODIFIER-MNEMONIC ¤òɽ¸½¤·¤Æ¤¤¤ë¡£ - - KEY-NAME ¤¬ 1 ¥Ð¥¤¥ÈŤǤ¢¤ë¾ì¹ç¡¢ÆþÎÏ¥­¡¼¤Ï¼¡¤Î¤è¤¦¤Ë¹½À®¤µ¤ì¤ë¡£ - - ¤Þ¤º¡¢keysym bits ¤Ë¤Ï¤½¤Î¥Ð¥¤¥È¥³¡¼¥É¤½¤Î¤â¤Î¤¬ÀßÄꤵ¤ì¤ë¡£ - - ¼¡¤¤¤Ç¡¢Shift, Control, Meta ¤Î³Æ¥â¥Ç¥£¥Õ¥¡¥¤¥¢¤Ï°Ê²¼¤Î¼ê³¤­¤Ç - keysym bits ¤ËÈ¿±Ç¤µ¤ì¤ë¡£ - - (1) Shift ¥â¥Ç¥£¥Õ¥¡¥¤¥¢¤¬¤¢¤ê¡¢keysym bits ¤¬¾®Ê¸»ú¤Ç¤¢¤ì¤Ð(¤Ä¤Þ - ¤ê 'a' ¤«¤é 'z' ¤Ç¤¢¤ì¤Ð), Âçʸ»ú (¤Ä¤Þ¤ê 'A' through 'Z') ¤ËÊÑ´¹ - ¤µ¤ì¤ë¡£Shift ¥â¥Ç¥£¥Õ¥¡¥¤¥¢¤Ï modifier bits ¤«¤é¼è¤ê½ü¤«¤ì¤ë¡£ - - (2) Control ¥â¥Ç¥£¥Õ¥¡¥¤¥¢¤¬¤¢¤ì¤Ð, keysym bits ¤Ï¥Ó¥Ã¥Èñ°Ì¤Ç - 0x1F ¤È and ±é»»¤ò¹Ô¤¦¡£Control ¥â¥Ç¥£¥Õ¥¡¥¤¥¢¤Ï modifier bits - ¤«¤é¼è¤ê½ü¤«¤ì¤ë¡£ - - (3) Meta ¥â¥Ç¥£¥Õ¥¡¥¤¥¢¤¬¤¢¤ì¤Ð, keysym bits ¤Ï¥Ó¥Ã¥Èñ°Ì¤Ç 0x80 - ¤È or ±é»»¤ò¹Ô¤¦¡£ Meta ¥â¥Ç¥£¥Õ¥¡¥¤¥¢¤Ï modifier bits ¤«¤é¼è¤ê½ü - ¤«¤ì¤ë¡£ - - ¤¿¤È¤¨¤Ð¡¢"S-a" ¤È "A" ¤Ï¤É¤Á¤é¤â 65 ¤ò¡¢"C-a" ¤È "C-A" ¤Ï¤É¤Á¤é¤â - 1 ¤òÊÖ¤·¡¢"M-a" ¤Ï 225 ¤ò, "C-M-a" ¤Ï 129 ¤òÊÖ¤¹¡£ - - KEY-NAME ¤¬ 2 ¥Ð¥¤¥È°Ê¾å¤Ç¤¢¤ë»þ¤Ë¤Ï¡¢Âбþ¤¹¤ëkeysym bits ¤Ï@c - m17n @c ¥é¥¤¥Ö¥é¥ê ÆâÉô¤Î¥Æ¡¼¥Ö¥ë¤Ë¤è¤Ã¤ÆÆÀ¤ë»ö¤¬¤Ç¤­¤ë¡£¤³¤Î¤È¤­ - ¥Æ¡¼¥Ö¥ë¤Ë KEY-NAME ¤¬¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï -1 ¤òÊÖ¤¹¡£ */ - -MSymbol -minput_event_to_key (MFrame *frame, void *event) -{ - int modifiers; - MSymbol key = mwin__parse_event (frame, event, &modifiers); - char *name, *str; - - if (! modifiers) - return key; - - name = msymbol_name (key); - str = alloca (strlen (name) + 2 * 6 + 1); - str[0] = '\0'; - if (modifiers & MINPUT_KEY_SHIFT_MODIFIER) - strcat (str, "S-"); - if (modifiers & MINPUT_KEY_CONTROL_MODIFIER) - strcat (str, "C-"); - if (modifiers & MINPUT_KEY_META_MODIFIER) - strcat (str, "M-"); - if (modifiers & MINPUT_KEY_ALT_MODIFIER) - strcat (str, "A-"); - if (modifiers & MINPUT_KEY_SUPER_MODIFIER) - strcat (str, "s-"); - if (modifiers & MINPUT_KEY_HYPER_MODIFIER) - strcat (str, "H-"); - strcat (str, name); - - return msymbol (str); -} - -/*** @} */ - -/* - Local Variables: - coding: euc-japan - End: -*/ diff --git a/src/input.c b/src/input.c deleted file mode 100644 index 5f1c920..0000000 --- a/src/input.c +++ /dev/null @@ -1,2358 +0,0 @@ -/* input.c -- input method module. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -/***en - @addtogroup m17nInputMethod - @brief API for Input method - - An input method is an object to enable inputting various - characters. An input method is identified by a pair of symbols, - LANGUAGE and NAME. This pair decides an input driver of the input - method. An input driver is a set of functions for handling the - input method. There are two kinds of input methods; internal one - and foreign one. - -
    - -
  • Internal Input Method - - An internal input method has non @c Mnil LANGUAGE, and the body is - defined in the m17n database by the tag . For this kind of input methods, the m17n library uses two - predefined input method drivers, one for CUI use and the other for - GUI use. Those driver utilize the input processing engine - provided by the m17n library itself. The m17n database may - provides an input method that is not only for a specific language. - The database uses @c Mt as the language of such an input method. - - An internal input method accepts an input key which is a symbol - associated with an input event. As there is no way for the @c - m17n @c library to know how input events are represented in an - application program, a application programmer have to convert an - input event to an input key by himself. See the documentation of - the function minput_event_to_key () for the detail. - -
  • Foreign Input Method - - A foreign input method has @c Mnil LANGUAGE, and the body is - defined in an external resources (e.g. XIM of X Window System). - For this kind of input methods, the symbol NAME must have a - property of key @c Minput_driver, and the value must be a pointer - to an input driver. So, by preparing a proper input - driver, any kind of input method can be treated in the framework - of the @c m17n @c library. - - For convenience, the m17n-X library provides an input driver that - enables the input style of OverTheSpot for XIM, and stores @c - Minput_driver property of the symbol @c Mxim with a pointer to - that driver. See the documentation of m17n GUI API for the - detail. - -
- - PROCESSING FLOW - - The typical processing flow of handling an input method is: open - an input method, create an input context for the input method, - filter an input key, and looking up a produced text in the input - context. */ - -/*=*/ - -/***ja - @addtogroup m17nInputMethod - @brief ÆþÎϥ᥽¥Ã¥ÉÍÑAPI - - ÆþÎϥ᥽¥Ã¥É¤Ï¿ÍͤÊʸ»ú¤òÆþÎϤ¹¤ë¤¿¤á¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¡£ÆþÎÏ¥á - ¥½¥Ã¥É¤Ï¥·¥ó¥Ü¥ë LANGUAGE ¤È NAME ¤ÎÁȤˤè¤Ã¤Æ¼±Ê̤µ¤ì¡¢¤³¤ÎÁȤˤè¤Ã - ¤ÆÆþÎϥɥ饤¥Ð¤¬·è¤Þ¤ë¡£ÆþÎϥɥ饤¥Ð¤È¤Ï»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ò°·¤¦¤¿ - ¤á¤Î´Ø¿ô¤Î½¸¤Þ¤ê¤Ç¤¢¤ë¡£ - - ÆþÎϥ᥽¥Ã¥É¤Ë¤ÏÆâÉô¥á¥½¥Ã¥É¤È³°Éô¥á¥½¥Ã¥É¤ÎÆóÄ̤꤬¤¢¤ë¡£ - - ÆâÉôÆþÎϥ᥽¥Ã¥É - - ÆâÉôÆþÎϥ᥽¥Ã¥É¤Ï LANGUAGE ¤¬ @c Mnil °Ê³°¤Î¤â¤Î¤Ç¤¢¤ê¡¢ËÜÂÎ¤Ï - m17n ¸À¸ì¾ðÊó¥Ù¡¼¥¹¤Ë ¤È¤¤¤¦¥¿¥°ÉÕ - ¤­¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë¡£¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤ËÂФ·¤Æ¡¢m17n¥é¥¤¥Ö¥é¥ê¤Ë - ¤ÏCUIÍѤÈGUIÍѤ½¤ì¤¾¤ì¤ÎÆþÎϥɥ饤¥Ð¤¬¤¢¤é¤«¤¸¤á½àÈ÷¤µ¤ì¤Æ¤¤¤ë¡£¤³ - ¤ì¤é¤Î¥É¥é¥¤¥Ð¤Ïm17n¥é¥¤¥Ö¥é¥ê¼«¿È¤ÎÆþÎϽèÍý¥¨¥ó¥¸¥ó¤òÍøÍѤ¹¤ë¡£ - - ÆâÉôÆþÎϥ᥽¥Ã¥É¤Ï¡¢¥æ¡¼¥¶¤ÎÆþÎÏ¥¤¥Ù¥ó¥È¤ËÂбþ¤·¤¿ÆþÎÏ¥­¡¼¤ò¼õ¤±¼è - ¤ë¡£ÆþÎÏ¥­¡¼¤Ï¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÏÆþÎÏ¥¤¥Ù¥ó¥È - ¤¬¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¡¦¥×¥í¥°¥é¥à¤Ç¤É¤Î¤è¤¦¤Ëɽ¸½¤µ¤ì¤Æ¤¤¤ë¤«¤òÃΤë½Ñ - ¤ò»ý¤¿¤Ê¤¤¤Î¤Ç¡¢ÆþÎÏ¥¤¥Ù¥ó¥È¤«¤éÆþÎÏ¥­¡¼¤Ø¤ÎÊÑ´¹¤Ï¥×¥í¥°¥é¥Þ¤ÎÀÕǤ - ¤Ç¹Ô¤ï¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï´Ø¿ô minput_event_to_key () - ¤Î¥É¥­¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£ - - ³°ÉôÆþÎϥ᥽¥Ã¥É - - ³°ÉôÆþÎϥ᥽¥Ã¥É¤Ï LANGUAGE ¤¬ @c Mnil ¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤ÇËÜÂΤϳ°Éô - ¤Î¥ê¥½¡¼¥¹¤È¤·¤ÆÄêµÁ¤µ¤ì¤ë¡£¡Ê¤¿¤È¤¨¤ÐX Window System ¤ÎXIM ¤Ê¤É¡£) - ¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¥·¥ó¥Ü¥ë NAME ¤Ï@c Minput_driver ¤ò¥­¡¼¤È - ¤¹¤ë¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Á¡¢¤½¤ÎÃͤÏÆþÎϥɥ饤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê - ¤é¤Ê¤¤¡£¤·¤¿¤¬¤Ã¤Æ¡¢Å¬ÀÚ¤ÊÆþÎϥɥ饤¥Ð¤ò½àÈ÷¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢¤¤¤« - ¤Ê¤ëÆþÎϥ᥽¥Ã¥É¤â @c m17n @c ¥é¥¤¥Ö¥é¥ê¤ÎÏÈÁȤÎÃæ¤Ç°·¤¦»ö¤¬¤Ç¤­¤ë¡£ - - ´Êñ¤Î¤¿¤á¡¢m17n X ¥é¥¤¥Ö¥é¥ê¤ÏXIM ¤Î OverTheSpot ¤ÎÆþÎÏ¥¹¥¿¥¤¥ë¤ò - ¼Â¸½¤¹¤ëÆþÎϥɥ饤¥Ð¤òÄ󶡤·¤Æ¤¤¤ë¡£¤Þ¤¿¥·¥ó¥Ü¥ë @c Mxim ¤Î @c - Minput_driver ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤȤ·¤Æ¤½¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÝ»ý¤· - ¤Æ¤¤¤ë¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ïm17n-win API ¤Î¥É¥­¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£ - - ½èÍý¤Îή¤ì - - ÆþÎϥ᥽¥Ã¥É½èÍý¤Îŵ·¿Åª¤Ê½èÍý¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£ÆþÎϥ᥽¥Ã¥É¤Î¥ª¡¼ - ¥×¥ó¡¢¤½¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ÎÀ¸À®¡¢ÆþÎÏ¥¤¥Ù¥ó¥È¤Î¥Õ¥£ - ¥ë¥¿¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ç¤ÎÀ¸À®¥Æ¥­¥¹¥È¤Î¸¡º÷¡£ */ - -/*=*/ - -#if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE) -/*** @addtogroup m17nInternal - @{ */ - -#include -#include -#include - -#include "config.h" -#include "m17n-gui.h" -#include "m17n-misc.h" -#include "internal.h" -#include "mtext.h" -#include "input.h" -#include "symbol.h" -#include "plist.h" - -static MSymbol Minput_method; - -/** Symbols to load an input method data. */ -static MSymbol Mtitle, Mmacro, Mmodule, Mstate; - -/** Symbols for actions. */ -static MSymbol Minsert, Mdelete, Mmark, Mmove, Mpushback, Mundo, Mcall, Mshift; -static MSymbol Mselect, Mshow, Mhide; -static MSymbol Mset, Madd, Msub, Mmul, Mdiv, Mequal, Mless, Mgreater; - -static MSymbol Mcandidate_list, Mcandidate_index; - -static MSymbol Minit, Mfini; - -/** Symbols for key events. */ -static MSymbol one_char_symbol[256]; - -/** Structure to hold a map. */ - -struct MIMMap -{ - /** List of actions to take when we reach the map. In a root map, - the actions are executed only when there's no more key. */ - MPlist *map_actions; - - /** List of deeper maps. If NULL, this is a terminal map. */ - MPlist *submaps; - - /** List of actions to take when we leave the map successfully. In - a root map, the actions are executed only when none of submaps - handle the current key. */ - MPlist *branch_actions; -}; - -typedef MPlist *(*MIMExternalFunc) (MPlist *plist); - -typedef struct -{ - void *handle; - MPlist *func_list; /* function name vs (MIMExternalFunc *) */ -} MIMExternalModule; - -struct MIMState -{ - /** Name of the state. */ - MSymbol name; - - /** Title of the state, or NULL. */ - MText *title; - - /** Key translation map of the state. Built by merging all maps of - branches. */ - MIMMap *map; -}; - - -static int -marker_code (MSymbol sym) -{ - char *name; - - if (sym == Mnil) - return -1; - name = MSYMBOL_NAME (sym); - return ((name[0] == '@' - && ((name[1] >= '0' && name[1] <= '9') - || name[1] == '<' || name[1] == '>' - || name[1] == '=' || name[1] == '+' || name[1] == '-' - || name[1] == '[' || name[1] == ']') - && name[2] == '\0') - ? name[1] : -1); -} - -int -integer_value (MInputContext *ic, MPlist *arg) -{ - MInputContextInfo *ic_info = (MInputContextInfo *) ic->info; - int code; - MText *preedit = ic->preedit; - int len = mtext_nbytes (preedit); - - if (MPLIST_INTEGER_P (arg)) - return MPLIST_INTEGER (arg); - code = marker_code (MPLIST_SYMBOL (arg)); - if (code < 0) - return (int) mplist_get (ic_info->vars, MPLIST_SYMBOL (arg)); - if (code >= '0' && code <= '9') - code -= '0'; - else if (code == '=') - code = ic->cursor_pos; - else if (code == '-' || code == '[') - code = ic->cursor_pos - 1; - else if (code == '+' || code == ']') - code = ic->cursor_pos + 1; - else if (code == '<') - code = 0; - else if (code == '<') - code = len; - return (code >= 0 && code < len ? mtext_ref_char (preedit, code) : -1); -} - - -/* Parse PLIST as an action list while modifying the list to regularize - actions. PLIST should have this form: - PLIST ::= ( (ACTION-NAME ACTION-ARG *) *). - Return 0 if successfully parsed, otherwise return -1. */ - -static int -parse_action_list (MPlist *plist, MPlist *macros) -{ - MPLIST_DO (plist, plist) - { - if (MPLIST_MTEXT_P (plist)) - { - /* This is a short form of (insert MTEXT). */ - /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0) - MERROR (MERROR_IM, -1); */ - } - else if (MPLIST_PLIST_P (plist) - && (MPLIST_MTEXT_P (MPLIST_PLIST (plist)) - || MPLIST_PLIST_P (MPLIST_PLIST (plist)))) - { - MPlist *pl; - - /* This is a short form of (insert (GROUPS *)). */ - MPLIST_DO (pl, MPLIST_PLIST (plist)) - { - if (MPLIST_PLIST_P (pl)) - { - MPlist *elt; - - MPLIST_DO (elt, MPLIST_PLIST (pl)) - if (! MPLIST_MTEXT_P (elt) - || mtext_nchars (MPLIST_MTEXT (elt)) == 0) - MERROR (MERROR_IM, -1); - } - else - { - if (! MPLIST_MTEXT_P (pl) - || mtext_nchars (MPLIST_MTEXT (pl)) == 0) - MERROR (MERROR_IM, -1); - } - } - } - else if (MPLIST_INTEGER_P (plist)) - { - int c = MPLIST_INTEGER (plist); - - if (c < 0 || c > MCHAR_MAX) - MERROR (MERROR_IM, -1); - } - else if (MPLIST_PLIST_P (plist) - && MPLIST_SYMBOL_P (MPLIST_PLIST (plist))) - { - MPlist *pl = MPLIST_PLIST (plist); - MSymbol action_name = MPLIST_SYMBOL (pl); - - pl = MPLIST_NEXT (pl); - - if (action_name == Minsert) - { - if (MPLIST_MTEXT_P (pl)) - { - if (mtext_nchars (MPLIST_MTEXT (pl)) == 0) - MERROR (MERROR_IM, -1); - } - else if (MPLIST_PLIST_P (pl)) - { - MPLIST_DO (pl, pl) - { - if (MPLIST_PLIST_P (pl)) - { - MPlist *elt; - - MPLIST_DO (elt, MPLIST_PLIST (pl)) - if (! MPLIST_MTEXT_P (elt) - || mtext_nchars (MPLIST_MTEXT (elt)) == 0) - MERROR (MERROR_IM, -1); - } - else - { - if (! MPLIST_MTEXT_P (pl) - || mtext_nchars (MPLIST_MTEXT (pl)) == 0) - MERROR (MERROR_IM, -1); - } - } - } - else if (! MPLIST_SYMBOL_P (pl)) - MERROR (MERROR_IM, -1); - } - else if (action_name == Mselect - || action_name == Mdelete - || action_name == Mmove) - { - if (! MPLIST_SYMBOL_P (pl) - && ! MPLIST_INTEGER_P (pl)) - MERROR (MERROR_IM, -1); - } - else if (action_name == Mmark - || action_name == Mcall - || action_name == Mshift) - { - if (! MPLIST_SYMBOL_P (pl)) - MERROR (MERROR_IM, -1); - } - else if (action_name == Mshow || action_name == Mhide - || action_name == Mundo) - { - if (! MPLIST_TAIL_P (pl)) - MERROR (MERROR_IM, -1); - } - else if (action_name == Mpushback) - { - if (! MPLIST_INTEGER_P (pl)) - MERROR (MERROR_IM, -1); - } - else if (action_name == Mset || action_name == Madd - || action_name == Msub || action_name == Mmul - || action_name == Mdiv) - { - if (! (MPLIST_SYMBOL_P (pl) - && (MPLIST_INTEGER_P (MPLIST_NEXT (pl)) - || MPLIST_SYMBOL_P (MPLIST_NEXT (pl))))) - MERROR (MERROR_IM, -1); - } - else if (action_name == Mequal || action_name == Mless - || action_name == Mgreater) - { - if (! ((MPLIST_INTEGER_P (pl) || MPLIST_SYMBOL_P (pl)) - && (MPLIST_INTEGER_P (MPLIST_NEXT (pl)) - || MPLIST_SYMBOL_P (MPLIST_NEXT (pl))))) - MERROR (MERROR_IM, -1); - pl = MPLIST_NEXT (MPLIST_NEXT (pl)); - if (! MPLIST_PLIST_P (pl)) - MERROR (MERROR_IM, -1); - if (parse_action_list (MPLIST_PLIST (pl), macros) < 0) - MERROR (MERROR_IM, -1); - pl = MPLIST_NEXT (pl); - if (MPLIST_PLIST_P (pl) - && parse_action_list (MPLIST_PLIST (pl), macros) < 0) - MERROR (MERROR_IM, -1); - } - else if (! macros || ! mplist_get (macros, action_name)) - MERROR (MERROR_IM, -1); - } - else - MERROR (MERROR_IM, -1); - } - - return 0; -} - - -/* Load a translation into MAP from PLIST. - PLIST has this form: - PLIST ::= ( KEYSEQ MAP-ACTION * ) */ - -static int -load_translation (MIMMap *map, MPlist *plist, MPlist *branch_actions, - MPlist *macros) -{ - MSymbol *keyseq; - int len, i; - - if (MPLIST_MTEXT_P (plist)) - { - MText *mt = MPLIST_MTEXT (plist); - - len = mtext_nchars (mt); - if (len == 0 || len != mtext_nbytes (mt)) - MERROR (MERROR_IM, -1); - keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len); - for (i = 0; i < len; i++) - keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]]; - } - else if (MPLIST_PLIST_P (plist)) - { - MPlist *elt = MPLIST_PLIST (plist); - - len = MPLIST_LENGTH (elt); - if (len == 0) - MERROR (MERROR_IM, -1); - keyseq = (MSymbol *) alloca (sizeof (int) * len); - for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt)) - { - if (MPLIST_INTEGER_P (elt)) - { - int c = MPLIST_INTEGER (elt); - - if (c < 0 || c >= 0x100) - MERROR (MERROR_IM, -1); - keyseq[i] = one_char_symbol[c]; - } - else if (MPLIST_SYMBOL_P (elt)) - keyseq[i] = MPLIST_SYMBOL (elt); - else - MERROR (MERROR_IM, -1); - } - } - else - MERROR (MERROR_IM, -1); - - for (i = 0; i < len; i++) - { - MIMMap *deeper = NULL; - - if (map->submaps) - deeper = mplist_get (map->submaps, keyseq[i]); - else - map->submaps = mplist (); - if (! deeper) - { - /* Fixme: It is better to make all deeper maps at once. */ - MSTRUCT_CALLOC (deeper, MERROR_IM); - mplist_put (map->submaps, keyseq[i], deeper); - } - map = deeper; - } - - /* We reach a terminal map. */ - if (map->map_actions - || map->branch_actions) - /* This map is already defined. We avoid overriding it. */ - return 0; - - plist = MPLIST_NEXT (plist); - if (! MPLIST_TAIL_P (plist)) - { - if (parse_action_list (plist, macros) < 0) - MERROR (MERROR_IM, -1); - map->map_actions = plist; - M17N_OBJECT_REF (plist); - } - if (branch_actions) - { - map->branch_actions = branch_actions; - M17N_OBJECT_REF (branch_actions); - } - - return 0; -} - -/* Load a branch from PLIST into MAP. PLIST has this form: - PLIST ::= ( MAP-NAME BRANCH-ACTION * ) - MAPS is a plist of raw maps. - STATE is the current state. */ - -static int -load_branch (MPlist *plist, MPlist *maps, MIMMap *map, MPlist *macros) -{ - MSymbol map_name; - MPlist *branch_actions; - - if (! MPLIST_SYMBOL_P (plist)) - MERROR (MERROR_IM, -1); - map_name = MPLIST_SYMBOL (plist); - plist = MPLIST_NEXT (plist); - if (MPLIST_TAIL_P (plist)) - branch_actions = NULL; - else if (parse_action_list (plist, macros) < 0) - MERROR (MERROR_IM, -1); - else - branch_actions = plist; - if (map_name == Mnil) - { - map->branch_actions = branch_actions; - if (branch_actions) - M17N_OBJECT_REF (branch_actions); - } - else if (map_name == Mt) - { - map->map_actions = branch_actions; - if (branch_actions) - M17N_OBJECT_REF (branch_actions); - } - else - { - plist = (MPlist *) mplist_get (maps, map_name); - if (! plist || ! MPLIST_PLIST_P (plist)) - MERROR (MERROR_IM, -1); - MPLIST_DO (plist, plist) - if (! MPLIST_PLIST_P (plist) - || (load_translation (map, MPLIST_PLIST (plist), branch_actions, - macros) - < 0)) - MERROR (MERROR_IM, -1); - } - - return 0; -} - -/* Load a macro from PLIST into MACROS. - PLIST has this from: - PLIST ::= ( MACRO-NAME ACTION * ) - MACROS is a plist of macro names vs action list. */ -static int -load_macros (MPlist *plist, MPlist *macros) -{ - MSymbol name; - - if (! MPLIST_SYMBOL_P (plist)) - MERROR (MERROR_IM, -1); - name = MPLIST_SYMBOL (plist); - plist = MPLIST_NEXT (plist); - if (MPLIST_TAIL_P (plist) - || parse_action_list (plist, macros) < 0) - MERROR (MERROR_IM, -1); - mplist_put (macros, name, plist); - M17N_OBJECT_REF (plist); - return 0; -} - -/* Load an external module from PLIST into EXTERNALS. - PLIST has this form: - PLIST ::= ( MODULE-NAME FUNCTION * ) - EXTERNALS is a plist of MODULE-NAME vs (MIMExternalModule *). */ - -#ifndef DLOPEN_SHLIB_EXT -#define DLOPEN_SHLIB_EXT ".so" -#endif - -static int -load_external_module (MPlist *plist, MPlist *externals) -{ - void *handle; - MSymbol module; - char *module_file; - MIMExternalModule *external; - MPlist *func_list; - void *func; - - if (MPLIST_MTEXT_P (plist)) - module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist))); - else if (MPLIST_SYMBOL_P (plist)) - module = MPLIST_SYMBOL (plist); - module_file = alloca (strlen (MSYMBOL_NAME (module)) - + strlen (DLOPEN_SHLIB_EXT) + 1); - sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT); - - handle = dlopen (module_file, RTLD_NOW); - if (! handle) - { - fprintf (stderr, "%s\n", dlerror ()); - MERROR (MERROR_IM, -1); - } - func_list = mplist (); - MPLIST_DO (plist, MPLIST_NEXT (plist)) - { - if (! MPLIST_SYMBOL_P (plist)) - MERROR_GOTO (MERROR_IM, err_label); - func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist))); - if (! func) - MERROR_GOTO (MERROR_IM, err_label); - mplist_add (func_list, MPLIST_SYMBOL (plist), func); - } - - MSTRUCT_MALLOC (external, MERROR_IM); - external->handle = handle; - external->func_list = func_list; - mplist_add (externals, module, external); - return 0; - - err_label: - dlclose (handle); - M17N_OBJECT_UNREF (func_list); - return -1; -} - - -/** Load a state from PLIST into a newly allocated state object. - PLIST has this form: - PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * ) - BRANCH ::= ( MAP-NAME BRANCH-ACTION * ) - MAPS is a plist of defined maps. - Return the state object. */ - -static MIMState * -load_state (MPlist *plist, MPlist *maps, MSymbol language, MPlist *macros) -{ - MIMState *state; - - MSTRUCT_CALLOC (state, MERROR_IM); - if (! MPLIST_SYMBOL_P (plist)) - MERROR (MERROR_IM, NULL); - state->name = MPLIST_SYMBOL (plist); - plist = MPLIST_NEXT (plist); - if (MPLIST_MTEXT_P (plist)) - { - state->title = MPLIST_MTEXT (plist); - mtext_put_prop (state->title, 0, mtext_nchars (state->title), - Mlanguage, language); - M17N_OBJECT_REF (state->title); - plist = MPLIST_NEXT (plist); - } - MSTRUCT_CALLOC (state->map, MERROR_IM); - MPLIST_DO (plist, plist) - if (! MPLIST_PLIST_P (plist) - || load_branch (MPLIST_PLIST (plist), maps, state->map, macros) < 0) - MERROR (MERROR_IM, NULL); - return state; -} - - -static void -free_map (MIMMap *map) -{ - MPlist *plist; - - M17N_OBJECT_UNREF (map->map_actions); - if (map->submaps) - { - MPLIST_DO (plist, map->submaps) - free_map ((MIMMap *) MPLIST_VAL (plist)); - M17N_OBJECT_UNREF (map->submaps); - } - M17N_OBJECT_UNREF (map->branch_actions); - free (map); -} - -/* Load an input method from PLIST into IM_INTO, and return it. */ - -static int -load_input_method (MSymbol language, MSymbol name, MPlist *plist, - MInputMethodInfo *im_info) -{ - MText *title = NULL; - MPlist *maps = NULL; - MPlist *states = NULL; - MPlist *externals = NULL; - MPlist *macros = NULL; - MPlist *elt; - - if (! MPLIST_PLIST_P (plist)) - MERROR (MERROR_IM, -1); - for (; MPLIST_PLIST_P (plist); plist = MPLIST_NEXT (plist)) - { - elt = MPLIST_PLIST (plist); - if (! MPLIST_SYMBOL_P (elt)) - MERROR_GOTO (MERROR_IM, err); - if (MPLIST_SYMBOL (elt) == Mtitle) - { - elt = MPLIST_NEXT (elt); - if (MPLIST_MTEXT_P (elt)) - { - title = MPLIST_MTEXT (elt); - M17N_OBJECT_REF (title); - } - else - MERROR_GOTO (MERROR_IM, err); - } - else if (MPLIST_SYMBOL (elt) == Mmap) - { - maps = mplist__from_alist (MPLIST_NEXT (elt)); - if (! maps) - MERROR_GOTO (MERROR_IM, err); - } - else if (MPLIST_SYMBOL (elt) == Mmacro) - { - macros = mplist (); - MPLIST_DO (elt, MPLIST_NEXT (elt)) - { - if (! MPLIST_PLIST_P (elt) - || load_macros (MPLIST_PLIST (elt), macros) < 0) - MERROR_GOTO (MERROR_IM, err); - } - } - else if (MPLIST_SYMBOL (elt) == Mmodule) - { - externals = mplist (); - MPLIST_DO (elt, MPLIST_NEXT (elt)) - { - if (! MPLIST_PLIST_P (elt) - || load_external_module (MPLIST_PLIST (elt), externals) < 0) - MERROR_GOTO (MERROR_IM, err); - } - } - else if (MPLIST_SYMBOL (elt) == Mstate) - { - states = mplist (); - MPLIST_DO (elt, MPLIST_NEXT (elt)) - { - MIMState *state; - - if (! MPLIST_PLIST_P (elt)) - MERROR_GOTO (MERROR_IM, err); - state = load_state (MPLIST_PLIST (elt), maps, language, macros); - if (! state) - MERROR_GOTO (MERROR_IM, err); - mplist_put (states, state->name, state); - } - } - } - - MPLIST_DO (elt, maps) - M17N_OBJECT_UNREF (MPLIST_VAL (elt)); - M17N_OBJECT_UNREF (maps); - im_info->title = title; - im_info->externals = externals; - im_info->macros = macros; - im_info->states = states; - return 0; - - err: - if (maps) - { - MPLIST_DO (elt, maps) - M17N_OBJECT_UNREF (MPLIST_VAL (elt)); - M17N_OBJECT_UNREF (maps); - } - if (title) - M17N_OBJECT_UNREF (title); - if (states) - { - MPLIST_DO (plist, states) - { - MIMState *state = (MIMState *) MPLIST_VAL (plist); - - if (state->title) - M17N_OBJECT_UNREF (state->title); - if (state->map) - free_map (state->map); - free (state); - } - M17N_OBJECT_UNREF (states); - } - if (externals) - { - MPLIST_DO (plist, externals) - { - MIMExternalModule *external = MPLIST_VAL (plist); - - dlclose (external->handle); - M17N_OBJECT_UNREF (external->func_list); - free (external); - MPLIST_KEY (plist) = Mt; - } - M17N_OBJECT_UNREF (externals); - } - return -1; -} - - - -static int take_action_list (MInputContext *ic, MPlist *action_list); - -static void -shift_state (MInputContext *ic, MSymbol state_name) -{ - MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info; - MInputContextInfo *ic_info = (MInputContextInfo *) ic->info; - MIMState *state = ic_info->state; - - /* Find a state to shift to. If not found, shift to the initial - state. */ - state = (MIMState *) mplist_get (im_info->states, state_name); - if (! state) - state = (MIMState *) MPLIST_VAL (im_info->states); - - /* Enter the new state. */ - ic_info->state = state; - ic_info->map = state->map; - ic_info->state_key_head = ic_info->key_head; - if (state == (MIMState *) MPLIST_VAL (im_info->states)) - { - /* We have shifted to the initial state. */ - MPlist *p; - - mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit), - Mcandidate_list, NULL, 0); - mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit), - Mcandidate_index, NULL, 0); - mtext_cat (ic->produced, ic->preedit); - mtext_reset (ic->preedit); - ic->candidate_list = NULL; - ic->candidate_show = 0; - ic->preedit_changed = ic->candidates_changed = 1; - MPLIST_DO (p, ic_info->markers) - MPLIST_VAL (p) = 0; - MPLIST_DO (p, ic_info->vars) - MPLIST_VAL (p) = 0; - ic->cursor_pos = 0; - memmove (ic_info->keys, ic_info->keys + ic_info->state_key_head, - sizeof (int) * (ic_info->used - ic_info->state_key_head)); - ic_info->used -= ic_info->state_key_head; - ic_info->state_key_head = ic_info->key_head = 0; - } - mtext_cpy (ic_info->preedit_saved, ic->preedit); - ic_info->state_pos = ic->cursor_pos; - ic->status = state->title; - if (! ic->status) - ic->status = im_info->title; - ic->status_changed = 1; - if (ic_info->key_head == ic_info->used - && ic_info->map == ic_info->state->map - && ic_info->map->map_actions) - take_action_list (ic, ic_info->map->map_actions); -} - - -static MPlist * -find_candidates_group (MPlist *plist, int index, - int *start_index, int *end_index, int *group_index) -{ - int i = 0, gidx = 0, len; - - MPLIST_DO (plist, plist) - { - if (MPLIST_MTEXT_P (plist)) - len = mtext_nchars (MPLIST_MTEXT (plist)); - else - len = mplist_length (MPLIST_PLIST (plist)); - if (i + len > index) - { - if (start_index) - *start_index = i; - if (end_index) - *end_index = i + len; - if (group_index) - *group_index = gidx; - return plist; - } - i += len; - gidx++; - } - return NULL; -} - -static void -preedit_insert (MInputContext *ic, int pos, MText *mt, int c) -{ - MInputContextInfo *ic_info = ((MInputContext *) ic)->info; - MPlist *markers; - int nchars = mt ? mtext_nchars (mt) : 1; - - if (mt) - mtext_ins (ic->preedit, pos, mt); - else - mtext_ins_char (ic->preedit, pos, c, 1); - MPLIST_DO (markers, ic_info->markers) - if (MPLIST_INTEGER (markers) > pos) - MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + nchars); - if (ic->cursor_pos >= pos) - ic->cursor_pos += nchars; - ic->preedit_changed = 1; -} - - -static void -preedit_delete (MInputContext *ic, int from, int to) -{ - MInputContextInfo *ic_info = ((MInputContext *) ic)->info; - MPlist *markers; - - mtext_del (ic->preedit, from, to); - MPLIST_DO (markers, ic_info->markers) - { - if (MPLIST_INTEGER (markers) > to) - MPLIST_VAL (markers) - = (void *) (MPLIST_INTEGER (markers) - (to - from)); - else if (MPLIST_INTEGER (markers) > from); - MPLIST_VAL (markers) = (void *) from; - } - if (ic->cursor_pos >= to) - ic->cursor_pos -= to - from; - else if (ic->cursor_pos > from) - ic->cursor_pos = from; - ic->preedit_changed = 1; -} - - -static int -new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt) -{ - int code = marker_code (sym); - - if (mt && (code == '[' || code == ']')) - { - int pos = current; - - if (code == '[' && current > 0) - { - if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1) - && pos > 0) - current = pos; - } - else if (code == ']' && current < mtext_nchars (mt)) - { - if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1)) - current = pos; - } - return current; - } - if (code >= 0) - return (code == '<' ? 0 - : code == '>' ? limit - : code == '-' ? current - 1 - : code == '+' ? current + 1 - : code == '=' ? current - : code - '0' > limit ? limit - : code - '0'); - if (! ic) - return 0; - return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym); -} - -static void -udpate_candidate (MInputContext *ic, MTextProperty *prop, int idx) -{ - int from = mtext_property_start (prop); - int to = mtext_property_end (prop); - int start; - MPlist *candidate_list = mtext_property_value (prop); - MPlist *group = find_candidates_group (candidate_list, idx, &start, - NULL, NULL); - int ingroup_index = idx - start; - MText *mt; - - preedit_delete (ic, from, to); - if (MPLIST_MTEXT_P (group)) - { - mt = MPLIST_MTEXT (group); - preedit_insert (ic, from, NULL, mtext_ref_char (mt, ingroup_index)); - to = from + 1; - } - else - { - int i; - MPlist *plist; - - for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index; - i++, plist = MPLIST_NEXT (plist)); - mt = MPLIST_MTEXT (plist); - preedit_insert (ic, from, mt, 0); - to = from + mtext_nchars (mt); - } - mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list); - mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx); - ic->cursor_pos = to; -} - - -static int -take_action_list (MInputContext *ic, MPlist *action_list) -{ - MInputContextInfo *ic_info = (MInputContextInfo *) ic->info; - MPlist *candidate_list = ic->candidate_list; - int candidate_index = ic->candidate_index; - int candidate_show = ic->candidate_show; - MTextProperty *prop; - - MPLIST_DO (action_list, action_list) - { - MPlist *action; - MSymbol name; - MPlist *args; - - if (MPLIST_MTEXT_P (action_list) - || MPLIST_INTEGER_P (action_list)) - name = Minsert, args = action_list; - else if (MPLIST_PLIST_P (action_list) - && (MPLIST_MTEXT_P (MPLIST_PLIST (action_list)) - || MPLIST_PLIST_P (MPLIST_PLIST (action_list)))) - name = Minsert, args = action_list; - else - { - action = MPLIST_PLIST (action_list); - name = MPLIST_SYMBOL (action); - args = MPLIST_NEXT (action); - } - - if (name == Minsert) - { - if (MPLIST_MTEXT_P (args)) - preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0); - else if (MPLIST_INTEGER_P (args)) - preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args)); - else if (MPLIST_SYMBOL_P (args)) - { - int c = integer_value (ic, args); - - if (c >= 0 && c <= MCHAR_MAX) - preedit_insert (ic, ic->cursor_pos, NULL, c); - } - else - { - MText *mt; - int len; - - args = MPLIST_PLIST (args); - if (MPLIST_MTEXT_P (args)) - { - preedit_insert (ic, ic->cursor_pos, NULL, - mtext_ref_char (MPLIST_MTEXT (args), 0)); - len = 1; - } - else - { - mt = MPLIST_MTEXT (MPLIST_PLIST (args)); - preedit_insert (ic, ic->cursor_pos, mt, 0); - len = mtext_nchars (mt); - } - mtext_put_prop (ic->preedit, - ic->cursor_pos - len, ic->cursor_pos, - Mcandidate_list, args); - mtext_put_prop (ic->preedit, - ic->cursor_pos - len, ic->cursor_pos, - Mcandidate_index, (void *) 0); - } - } - else if (name == Mselect) - { - int start, end; - int code, idx, gindex; - int pos = ic->cursor_pos; - MPlist *group; - - if (pos == 0 - || ! (prop = mtext_get_property (ic->preedit, pos - 1, - Mcandidate_list))) - continue; - if (MPLIST_SYMBOL_P (args)) - { - code = marker_code (MPLIST_SYMBOL (args)); - if (code < 0) - continue; - } - else - code = -1; - idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index); - group = find_candidates_group (mtext_property_value (prop), idx, - &start, &end, &gindex); - - if (code != '[' && code != ']') - { - idx = (start - + (code >= 0 - ? new_index (NULL, ic->candidate_index - start, - end - start - 1, MPLIST_SYMBOL (args), - NULL) - : MPLIST_INTEGER (args))); - if (idx < 0 - || (idx >= end - && MPLIST_TAIL_P (MPLIST_NEXT (group)))) - idx = 0; - } - else - { - int ingroup_index = idx - start; - int len; - - group = mtext_property_value (prop); - len = mplist_length (group); - if (code == '[') - { - gindex--; - if (gindex < 0) - gindex = len - 1;; - } - else - { - gindex++; - if (gindex >= len) - gindex = 0; - } - for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group)) - idx += (MPLIST_MTEXT_P (group) - ? mtext_nchars (MPLIST_MTEXT (group)) - : mplist_length (MPLIST_PLIST (group))); - len = (MPLIST_MTEXT_P (group) - ? mtext_nchars (MPLIST_MTEXT (group)) - : mplist_length (MPLIST_PLIST (group))); - if (ingroup_index >= len) - ingroup_index = len - 1; - idx += ingroup_index; - } - udpate_candidate (ic, prop, idx); - } - else if (name == Mshow) - ic->candidate_show = 1; - else if (name == Mhide) - ic->candidate_show = 0; - else if (name == Mdelete) - { - int len = mtext_nchars (ic->preedit); - int to = (MPLIST_SYMBOL_P (args) - ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args), - ic->preedit) - : MPLIST_INTEGER (args)); - - if (to < 0) - to = 0; - else if (to > len) - to = len; - if (to < ic->cursor_pos) - preedit_delete (ic, to, ic->cursor_pos); - else if (to > ic->cursor_pos) - preedit_delete (ic, ic->cursor_pos, to); - } - else if (name == Mmove) - { - int len = mtext_nchars (ic->preedit); - int pos - = (MPLIST_SYMBOL_P (args) - ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args), - ic->preedit) - : MPLIST_INTEGER (args)); - - if (pos < 0) - pos = 0; - else if (pos > len) - pos = len; - if (pos != ic->cursor_pos) - { - ic->cursor_pos = pos; - ic->preedit_changed = 1; - } - } - else if (name == Mmark) - { - int code = marker_code (MPLIST_SYMBOL (args)); - - if (code < 0) - mplist_put (ic_info->markers, MPLIST_SYMBOL (args), - (void *) ic->cursor_pos); - } - else if (name == Mpushback) - { - int num = MPLIST_INTEGER (args); - - if (num > 0) - ic_info->key_head -= num; - else - ic_info->key_head = num; - if (ic_info->key_head > ic_info->used) - ic_info->key_head = ic_info->used; - } - else if (name == Mcall) - { - MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info; - MIMExternalFunc func = NULL; - MSymbol module, func_name; - MPlist *func_args, *val; - int ret = 0; - - module = MPLIST_SYMBOL (args); - args = MPLIST_NEXT (args); - func_name = MPLIST_SYMBOL (args); - - if (im_info->externals) - { - MIMExternalModule *external - = (MIMExternalModule *) mplist_get (im_info->externals, - module); - if (external) - func = (MIMExternalFunc) mplist_get (external->func_list, - func_name); - } - if (! func) - continue; - func_args = mplist (); - mplist_add (func_args, Mt, ic); - MPLIST_DO (args, MPLIST_NEXT (args)) - { - int code; - - if (MPLIST_KEY (args) == Msymbol - && MPLIST_KEY (args) != Mnil - && (code = marker_code (MPLIST_SYMBOL (args))) >= 0) - { - code = new_index (ic, ic->cursor_pos, - mtext_nchars (ic->preedit), - MPLIST_SYMBOL (args), ic->preedit); - mplist_add (func_args, Minteger, (void *) code); - } - else - mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args)); - } - val = (func) (func_args); - M17N_OBJECT_UNREF (func_args); - if (val && ! MPLIST_TAIL_P (val)) - ret = take_action_list (ic, val); - M17N_OBJECT_UNREF (val); - if (ret < 0) - return ret; - } - else if (name == Mshift) - { - shift_state (ic, MPLIST_SYMBOL (args)); - } - else if (name == Mundo) - { - MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info; - int unhandle = 0; - - mtext_reset (ic->preedit); - mtext_reset (ic_info->preedit_saved); - ic->cursor_pos = ic_info->state_pos = 0; - ic_info->state_key_head = ic_info->key_head = 0; - ic_info->used -= 2; - if (ic_info->used < 0) - { - ic_info->used = 0; - unhandle = 1; - } - shift_state (ic, ((MIMState *) MPLIST_VAL (im_info->states))->name); - if (unhandle) - return -1; - break; - } - else if (name == Mset || name == Madd || name == Msub - || name == Mmul || name == Mdiv) - { - MSymbol sym = MPLIST_SYMBOL (args); - int val1 = (int) mplist_get (ic_info->vars, sym), val2; - - args = MPLIST_NEXT (args); - val2 = integer_value (ic, args); - if (name == Mset) - val1 = val2; - else if (name == Madd) - val1 += val2; - else if (name == Msub) - val1 -= val2; - else if (name == Mmul) - val1 *= val2; - else - val1 /= val2; - mplist_put (ic_info->vars, sym, (void *) val1); - } - else if (name == Mequal || name == Mless || name == Mgreater) - { - int val1, val2; - MPlist *actions1, *actions2; - int ret; - - val1 = integer_value (ic, args); - args = MPLIST_NEXT (args); - val2 = integer_value (ic, args); - args = MPLIST_NEXT (args); - actions1 = MPLIST_PLIST (args); - args = MPLIST_NEXT (args); - if (MPLIST_TAIL_P (args)) - actions2 = NULL; - else - actions2 = MPLIST_PLIST (args); - if (name == Mequal ? val1 == val2 - : name == Mless ? val1 < val2 - : val1 > val2) - ret = take_action_list (ic, actions1); - else if (actions2) - ret = take_action_list (ic, actions2); - if (ret < 0) - return ret; - } - else - { - MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info; - MPlist *actions; - - if (im_info->macros - && (actions = mplist_get (im_info->macros, name))) - { - if (take_action_list (ic, actions) < 0) - return -1; - }; - } - } - - prop = NULL; - ic->candidate_list = NULL; - if (ic->cursor_pos > 0 - && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1, - Mcandidate_list))) - { - ic->candidate_list = mtext_property_value (prop); - ic->candidate_index - = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1, - Mcandidate_index); - ic->candidate_from = mtext_property_start (prop); - ic->candidate_to = mtext_property_end (prop); - } - - ic->candidates_changed |= (candidate_list != ic->candidate_list - || candidate_index != ic->candidate_index - || candidate_show != ic->candidate_show); - return 0; -} - - -/* Handle the input key KEY in the current state and map specified in - the input context IC. If KEY is handled correctly, return 0. - Otherwise, return -1. */ - -static int -handle_key (MInputContext *ic) -{ - MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info; - MInputContextInfo *ic_info = (MInputContextInfo *) ic->info; - MIMMap *map = ic_info->map; - MIMMap *submap; - MSymbol key = ic_info->keys[ic_info->key_head]; - int i; - - submap = (map->submaps ? mplist_get (map->submaps, key) : NULL); - if (submap) - { - mtext_cpy (ic->preedit, ic_info->preedit_saved); - ic->cursor_pos = ic_info->state_pos; - ic_info->key_head++; - ic_info->map = map = submap; - if (map->map_actions) - { - if (take_action_list (ic, map->map_actions) < 0) - return -1; - } - else if (map->submaps) - { - for (i = ic_info->state_key_head; i < ic_info->key_head; i++) - { - MSymbol key = ic_info->keys[i]; - char *name = msymbol_name (key); - - if (! name[0] || ! name[1]) - mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1); - } - ic->preedit_changed = 1; - } - - /* If this is the terminal map or we have shifted to another - state, perform branch actions (if any). */ - if (! map->submaps || map != ic_info->map) - { - if (map->branch_actions) - { - if (take_action_list (ic, map->branch_actions) < 0) - return -1; - } - /* If MAP is still not the root map, shift to the current - state. */ - if (ic_info->map != ic_info->state->map) - shift_state (ic, ic_info->state->name); - } - } - else - { - /* MAP can not handle KEY. */ - - /* If MAP is the root map of the initial state, it means that - the current input method can not handle KEY. */ - if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map) - return -1; - - if (map != ic_info->state->map) - { - /* If MAP is not the root map... */ - /* If MAP has branch actions, perform them. */ - if (map->branch_actions) - take_action_list (ic, map->branch_actions); - /* If MAP is still not the root map, shift to the current - state. */ - if (ic_info->map != ic_info->state->map) - { - shift_state (ic, ic_info->state->name); - /* If MAP has branch_actions, perform them. */ - if (ic_info->map->branch_actions) - take_action_list (ic, ic_info->map->branch_actions); - } - } - else - { - /* MAP is the root map, perform branch actions (if any) or - shift to the initial state. */ - if (map->branch_actions) - take_action_list (ic, map->branch_actions); - else - shift_state (ic, - ((MIMState *) MPLIST_VAL (im_info->states))->name); - } - } - return 0; -} - -static void -reset_ic (MInputContext *ic) -{ - MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info; - MInputContextInfo *ic_info = (MInputContextInfo *) ic->info; - - MLIST_RESET (ic_info); - ic_info->state = (MIMState *) MPLIST_VAL (im_info->states); - ic_info->map = ic_info->state->map; - ic_info->state_key_head = ic_info->key_head = 0; - ic->cursor_pos = ic_info->state_pos = 0; - ic->status = ic_info->state->title; - if (! ic->status) - ic->status = im_info->title; - ic->candidate_list = NULL; - ic->candidate_show = 0; - ic->status_changed = ic->preedit_changed = ic->candidates_changed = 1; - if (ic_info->map->map_actions) - take_action_list (ic, ic_info->map->map_actions); -} - -static int -open_im (MInputMethod *im) -{ - MDatabase *mdb; - MInputMethodInfo *im_info; - MPlist *plist; - int result; - - mdb = mdatabase_find (Minput_method, im->language, im->name, Mnil); - if (! mdb) - return -1; - plist = mdatabase_load (mdb); - if (! plist) - MERROR (MERROR_IM, -1); - MSTRUCT_CALLOC (im_info, MERROR_IM); - im->info = im_info; - result = load_input_method (im->language, im->name, plist, im_info); - M17N_OBJECT_UNREF (plist); - if (result < 0) - MERROR (MERROR_IM, -1); - return 0; -} - -static void -close_im (MInputMethod *im) -{ - MInputMethodInfo *im_info = (MInputMethodInfo *) im->info; - MPlist *plist; - - if (im_info->title) - M17N_OBJECT_UNREF (im_info->title); - if (im_info->states) - { - MPLIST_DO (plist, im_info->states) - { - MIMState *state = (MIMState *) MPLIST_VAL (plist); - - if (state->title) - M17N_OBJECT_UNREF (state->title); - if (state->map) - free_map (state->map); - free (state); - } - M17N_OBJECT_UNREF (im_info->states); - } - - if (im_info->macros) - { - MPLIST_DO (plist, im_info->macros) - M17N_OBJECT_UNREF (MPLIST_VAL (plist)); - M17N_OBJECT_UNREF (im_info->macros); - } - - if (im_info->externals) - { - MPLIST_DO (plist, im_info->externals) - { - MIMExternalModule *external = MPLIST_VAL (plist); - - dlclose (external->handle); - M17N_OBJECT_UNREF (external->func_list); - free (external); - MPLIST_KEY (plist) = Mt; - } - M17N_OBJECT_UNREF (im_info->externals); - } - free (im_info); - im->info = NULL; -} - - -static int -create_ic (MInputContext *ic) -{ - MInputMethod *im = ic->im; - MInputMethodInfo *im_info = (MInputMethodInfo *) im->info; - MInputContextInfo *ic_info; - - if (ic->info) - ic_info = (MInputContextInfo *) ic->info; - else - { - MSTRUCT_CALLOC (ic_info, MERROR_IM); - ic->info = ic_info; - } - MLIST_INIT1 (ic_info, keys, 8); - ic_info->markers = mplist (); - ic_info->vars = mplist (); - ic_info->preedit_saved = mtext (); - if (im_info->externals) - { - MPlist *func_args = mplist (), *plist; - - mplist_add (func_args, Mt, ic); - MPLIST_DO (plist, im_info->externals) - { - MIMExternalModule *external = MPLIST_VAL (plist); - MIMExternalFunc func - = (MIMExternalFunc) mplist_get (external->func_list, Minit); - - if (func) - (func) (func_args); - } - M17N_OBJECT_UNREF (func_args); - } - reset_ic (ic); - return 0; -} - -static void -destroy_ic (MInputContext *ic) -{ - MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info; - MInputContextInfo *ic_info = (MInputContextInfo *) ic->info; - - if (im_info->externals) - { - MPlist *func_args = mplist (), *plist; - - mplist_add (func_args, Mt, ic); - MPLIST_DO (plist, im_info->externals) - { - MIMExternalModule *external = MPLIST_VAL (plist); - MIMExternalFunc func - = (MIMExternalFunc) mplist_get (external->func_list, Mfini); - - if (func) - (func) (func_args); - } - M17N_OBJECT_UNREF (func_args); - } - MLIST_FREE1 (ic_info, keys); - M17N_OBJECT_UNREF (ic_info->preedit_saved); - M17N_OBJECT_UNREF (ic_info->markers); - M17N_OBJECT_UNREF (ic_info->vars); - free (ic->info); -} - - -/** Handle the input key KEY in the current state and map of IC->info. - If KEY is handled but no text is produced, return 0, otherwise - return 1. - - Ignore ARG. */ - -static int -filter (MInputContext *ic, MSymbol key, void *arg) -{ - MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info; - MInputContextInfo *ic_info = (MInputContextInfo *) ic->info; - int i = 0; - - mtext_reset (ic->produced); - ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0; - MLIST_APPEND1 (ic_info, keys, key, MERROR_IM); - ic_info->key_unhandled = 0; - do { - if (handle_key (ic) < 0) - { - /* KEY was not handled. Reset the status and break the - loop. */ - reset_ic (ic); - /* This forces returning 1. */ - ic_info->key_unhandled = 1; - break; - } - if (i++ == 100) - { - mdebug_hook (); - reset_ic (ic); - ic_info->key_unhandled = 1; - break; - } - /* Break the loop if all keys were handled. */ - } while (ic_info->key_head < ic_info->used); - - /* If the current map is the root of the initial state, we should - produce any preedit text in ic->produced. */ - if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map - && mtext_nchars (ic->preedit) > 0) - shift_state (ic, ((MIMState *) MPLIST_VAL (im_info->states))->name); - - if (mtext_nchars (ic->produced) > 0) - { - MSymbol lang = msymbol_get (ic->im->language, Mlanguage); - - if (lang != Mnil) - mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced), - Mlanguage, ic->im->language); - } - - return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0); -} - - -/** Return 1 if the last event or key was not handled, otherwise - return 0. - - There is no need of looking up because ic->produced should already - contain the produced text (if any). - - Ignore KEY. */ - -static int -lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt) -{ - mtext_cat (mt, ic->produced); - mtext_reset (ic->produced); - return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0); -} - -/* Support functions for mdebug_dump_im. */ - -static void -dump_im_map (MPlist *map_list, int indent) -{ - char *prefix; - MSymbol key = MPLIST_KEY (map_list); - MIMMap *map = (MIMMap *) MPLIST_VAL (map_list); - - prefix = (char *) alloca (indent + 1); - memset (prefix, 32, indent); - prefix[indent] = '\0'; - - fprintf (stderr, "(\"%s\" ", msymbol_name (key)); - if (map->map_actions) - mdebug_dump_plist (map->map_actions, indent + 2); - if (map->submaps) - { - MPLIST_DO (map_list, map->submaps) - { - fprintf (stderr, "\n%s ", prefix); - dump_im_map (map_list, indent + 2); - } - } - if (map->branch_actions) - { - fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix); - mdebug_dump_plist (map->branch_actions, indent + 4); - fprintf (stderr, ")"); - } - fprintf (stderr, ")"); -} - - -static void -dump_im_state (MIMState *state, int indent) -{ - char *prefix; - MPlist *map_list; - - prefix = (char *) alloca (indent + 1); - memset (prefix, 32, indent); - prefix[indent] = '\0'; - - fprintf (stderr, "(%s", msymbol_name (state->name)); - if (state->map->submaps) - { - MPLIST_DO (map_list, state->map->submaps) - { - fprintf (stderr, "\n%s ", prefix); - dump_im_map (map_list, indent + 2); - } - } - fprintf (stderr, ")"); -} - - - -int -minput__init () -{ - char *key_names[32] - = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL }; - char buf[6], buf2[256]; - int i; - - Minput_method = msymbol ("input-method"); - Minput_driver = msymbol ("input-driver"); - Mtitle = msymbol ("title"); - Mmacro = msymbol ("macro"); - Mmodule = msymbol ("module"); - Mmap = msymbol ("map"); - Mstate = msymbol ("state"); - Minsert = msymbol ("insert"); - Mdelete = msymbol ("delete"); - Mmove = msymbol ("move"); - Mmark = msymbol ("mark"); - Mpushback = msymbol ("pushback"); - Mundo = msymbol ("undo"); - Mcall = msymbol ("call"); - Mshift = msymbol ("shift"); - Mselect = msymbol ("select"); - Mshow = msymbol ("show"); - Mhide = msymbol ("hide"); - Mset = msymbol ("set"); - Madd = msymbol ("add"); - Msub = msymbol ("sub"); - Mmul = msymbol ("mul"); - Mdiv = msymbol ("div"); - Mequal = msymbol ("="); - Mless = msymbol ("<"); - Mgreater = msymbol (">"); - - Minput_preedit_start = msymbol ("input-preedit-start"); - Minput_preedit_done = msymbol ("input-preedit-done"); - Minput_preedit_draw = msymbol ("input-preedit-draw"); - Minput_status_start = msymbol ("input-status-start"); - Minput_status_done = msymbol ("input-status-done"); - Minput_status_draw = msymbol ("input-status-draw"); - Minput_candidates_start = msymbol ("input-candidates-start"); - Minput_candidates_done = msymbol ("input-candidates-done"); - Minput_candidates_draw = msymbol ("input-candidates-draw"); - Minput_set_spot = msymbol ("input-set-spot"); - Minput_toggle = msymbol ("input-toggle"); - - Mcandidate_list = msymbol_as_managing_key (" candidate-list"); - Mcandidate_index = msymbol (" candidate-index"); - - Minit = msymbol ("init"); - Mfini = msymbol ("fini"); - - buf[0] = 'C'; - buf[1] = '-'; - buf[3] = '\0'; - for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++) - { - if (key_names[i]) - one_char_symbol[i] = msymbol (key_names[i]); - else - one_char_symbol[i] = msymbol (buf); - } - for (buf[2] = i; i < 127; i++, buf[2]++) - one_char_symbol[i] = msymbol (buf + 2); - one_char_symbol[i++] = msymbol ("Delete"); - buf[2] = 'M'; - buf[3] = '-'; - buf[5] = '\0'; - buf2[0] = 'M'; - buf2[1] = '-'; - for (buf[4] = '@'; i < 160; i++, buf[4]++) - { - if (key_names[i - 128]) - { - strcpy (buf2 + 2, key_names[i - 128]); - one_char_symbol[i] = msymbol (buf2); - } - else - one_char_symbol[i] = msymbol (buf); - } - for (buf[4] = i - 128; i < 255; i++, buf[2]++) - one_char_symbol[i] = msymbol (buf + 2); - one_char_symbol[i] = msymbol ("M-Delete"); - - minput_default_driver.open_im = open_im; - minput_default_driver.close_im = close_im; - minput_default_driver.create_ic = create_ic; - minput_default_driver.destroy_ic = destroy_ic; - minput_default_driver.filter = filter; - minput_default_driver.lookup = lookup; - minput_default_driver.callback_list = NULL; - minput_driver = &minput_default_driver; - return 0; -} - -void -minput__fini () -{ - if (minput_default_driver.callback_list) - { - M17N_OBJECT_UNREF (minput_default_driver.callback_list); - minput_default_driver.callback_list = NULL; - } - if (minput_driver->callback_list) - { - M17N_OBJECT_UNREF (minput_driver->callback_list); - minput_driver->callback_list = NULL; - } -} - -void -minput__callback (MInputContext *ic, MSymbol command) -{ - if (ic->im->driver.callback_list) - { - MInputCallbackFunc func - = (MInputCallbackFunc) mplist_get (ic->im->driver.callback_list, - command); - - if (func) - (func) (ic, command); - } -} - -MSymbol -minput__char_to_key (int c) -{ - if (c < 0 || c >= 0x100) - return Mnil; - - return one_char_symbol[c]; -} - -/*** @} */ -#endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */ - - -/* External API */ - -/*** @addtogroup m17nInputMethod */ -/*** @{ */ -/*=*/ - -/***en - @name Variables: Predefined symbols for callback commands. - - These are the predefined symbols that are used as the @c COMMAND - argument of callback functions of an input method driver (see - #MInputDriver::callback_list). */ -/*** @{ */ -/*=*/ - -MSymbol Minput_preedit_start; -MSymbol Minput_preedit_done; -MSymbol Minput_preedit_draw; -MSymbol Minput_status_start; -MSymbol Minput_status_done; -MSymbol Minput_status_draw; -MSymbol Minput_candidates_start; -MSymbol Minput_candidates_done; -MSymbol Minput_candidates_draw; -MSymbol Minput_set_spot; -MSymbol Minput_toggle; -/*** @} */ -/*=*/ - -/***en - @brief The default input driver for internal input methods. - - The variable #minput_default_driver is the default driver for - internal input methods. - - The member MInputDriver::open_im () searches the m17n database for - an input method that matches the tag \<#Minput_method, $LANGUAGE, - $NAME\> and loads it. - - The member MInputDriver::callback_list () is @c NULL. Thus, it is - programmers responsibility to set it to a plist of proper callback - functions. Otherwise, no feedback information (e.g. preedit text) - can be shown to users. - - The macro M17N_INIT () sets the variable #minput_driver to the - pointer to this driver so that all internal input methods use it. - - Therefore, unless @c minput_driver is set differently, the driver - dependent arguments $ARG of the functions whose name begin with - "minput_" are all ignored. */ - -/***ja - @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥ÈÆþÎϥɥ饤¥Ð - - ÆþÎϥɥ饤¥Ð minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë - ¥È¤ÎÆþÎϥɥ饤¥Ð¤Ç¤¢¤ë¡£ - - ¤³¤Î¥É¥é¥¤¥Ð¤Î ¥á¥ó¥Ð¤Ï @c NULL ¤Ê¤Î¤Ç¡¢¥×¥í¥°¥é¥Þ¦¤Ç - ÀÕǤ¤ò»ý¤Ã¤Æ, ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ËÀßÄꤷ¡¢Preedit ¥Æ¥­¥¹¥È, - Status ¥Æ¥­¥¹¥È¤¬¥æ¡¼¥¶¤Ëɽ¼¨¤Ç¤­¤ë¤è¤¦¤Ë¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ - - ´Ø¿ô M17N_INIT () ¤ÏÊÑ¿ô @c minput_driver ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó - ¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£ - - ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_ - ¤Ç»Ï¤Þ¤ë°Ê²¼¤Î´Ø¿ô·²¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤É¤ì¤â̵»ë¤µ¤ì - ¤ë¡£ */ - -MInputDriver minput_default_driver; -/*=*/ - -/***en - @brief The input driver for internal input methods. - - The variable #minput_driver is a pointer to the input method - driver that is used by internal input methods. The macro - M17N_INIT () initializes it to a pointer to #minput_default_driver - (if is included) or to #minput_gui_driver (if - is included). */ - -MInputDriver *minput_driver; - -MSymbol Minput_driver; - -/*=*/ - -/***en - @brief Open an input method. - - The minput_open_im () function opens an input method that matches - language $LANGUAGE and name $NAME, and returns a pointer to the - input method object newly allocated. - - This function at first decides an input driver for the input - method as below. - - If $LANGUAGE is not #Mnil, an input driver pointed by the variable - #minput_driver is used. - - If $LANGUAGE is #Mnil and $NAME has #Minput_driver property, the - input driver pointed to by the property value is used to open the - input method. If $NAME has no such property, @c NULL is returned. - - Then, the member MInputDriver::open_im () of the input driver is - called. - - $ARG is set in the member @c arg of the structure MInputMethod so - that the input driver can refer to it. */ - -/***ja - @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë - - ´Ø¿ô mim_open () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME ¤ËŬ¹ç¤¹¤ëÆþÎϥ᥽¥Ã - ¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¤½¤Î¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£ - - $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢m17n ¸À¸ì¾ðÊó¥Ù¡¼¥¹Ã椫¤é \<@c - Minput_method, $LANGUAGE, $NAME \> ¤È¤¤¤¦¥¿¥°¤ËŬ¹ç¤¹¤ëÆþÎϥ᥽¥Ã - ¥É¤òõ¤¹¡£¸«¤Ä¤«¤Ã¤¿¾ì¹ç¤Ï¡¢ÊÑ¿ô #minput_driver ¤Ç¥Ý¥¤¥ó¥È¤µ¤ì¤Æ - ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤Æ¤½¤ÎÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£¸«¤Ä¤«¤é¤Ê - ¤¤¾ì¹ç¤ä¥ª¡¼¥×¥ó¤Ç¤­¤Ê¤«¤Ã¤¿¾ì¹ç¤Ë¤Ï @c NULL ¤òÊÖ¤¹¡£ - - ÊÑ¿ô #minput_driver ¤Ï¡¢#minput_default_driver ¤« @c - minput_gui_driver ¤Î¤É¤Á¤é¤«¤ò¥Ý¥¤¥ó¥È¤·¤Æ¤¤¤ë¡£Á°¼Ô¤Ï CUI ÍѤǤ¢ - ¤ê¡¢´Ø¿ôm17n_initialize () ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤Æ #minput_driver ¤¬ - #minput_default_driver ¤ò¥Ý¥¤¥ó¥È¤¹¤ë¤è¤¦¤Ë¤Ê¤ë¡£¸å¼Ô¤Ï GUI ÍÑ¤Ç - ¤¢¤ê¡¢´Ø¿ô m17n_initialize_win () ¤Ë¤è¤Ã¤Æ¥Ý¥¤¥ó¥È¤µ¤ì¤ë¡£¾ÜºÙ¤Ë¤Ä - ¤¤¤Æ¤Ï¤³¤ì¤é¤ÎÊÑ¿ô¤Î¥É¥­¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£ - - $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver ¤ò¥­¡¼¤È¤¹ - ¤ë¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǥݥ¤¥ó¥È¤µ¤ì¤Æ¤¤¤ë - ÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£$NAME ¤Ë¤½¤Î¤è¤¦¤Ê - ¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤ä¥ª¡¼¥×¥ó¤Ç¤­¤Ê¤«¤Ã¤¿¾ì¹ç¤Ë¤Ï @c NULL ¤ò - ÊÖ¤¹¡£ - - $ARG ¤Ï¡¢ÆþÎϥɥ饤¥Ð¤¬»²¾È¤Ç¤­¤ë¤è¤¦¤Ë¡¢¹½Â¤ÂÎ MInputMethod ¤Î¥á - ¥ó¥Ð @c arg ¤Ë¥»¥Ã¥È¤µ¤ì¤ë¡£ - - @latexonly \IPAlabel{minput_open} @endlatexonly - -*/ - -MInputMethod * -minput_open_im (MSymbol language, MSymbol name, void *arg) -{ - MInputMethod *im; - MInputDriver *driver; - - if (language) - driver = minput_driver; - else - { - driver = (MInputDriver *) msymbol_get (name, Minput_driver); - if (! driver) - MERROR (MERROR_IM, NULL); - } - - MSTRUCT_CALLOC (im, MERROR_IM); - im->language = language; - im->name = name; - im->arg = arg; - im->driver = *driver; - if ((*im->driver.open_im) (im) < 0) - { - free (im); - return NULL; - } - return im; -} - -/*=*/ - -/***en - @brief Close an input method. - - The minput_close_im () function closes the input method $IM, which - must have been created by minput_open_im (). */ - -/***ja - @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë - - ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£¤³¤Î - ÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì - ¤Ð¤Ê¤é¤Ê¤¤¡£ */ - -void -minput_close_im (MInputMethod *im) -{ - (*im->driver.close_im) (im); - free (im); -} - -/*=*/ - -/***en - @brief Create an input context. - - The minput_create_ic () function creates an input context object - associated with input method $IM, and calls callback functions - corresponding to #Minput_preedit_start, #Minput_status_start, and - #Minput_status_draw in this order. - - @return - - If an input context is successfully created, minput_create_ic () - returns a pointer to it. Otherwise it returns @c NULL. */ - -/***ja - @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë - - ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯ - ¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤¹¤ë¡£ - - @return - ½èÍý¤¬À®¸ù¤·¤¿¾ì¹ç¡¢minput_create_ic () ¤ÏÀ¸À®¤·¤¿ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È - ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£ */ - -MInputContext * -minput_create_ic (MInputMethod *im, void *arg) -{ - MInputContext *ic; - - MSTRUCT_CALLOC (ic, MERROR_IM); - ic->im = im; - ic->arg = arg; - ic->preedit = mtext (); - ic->candidate_list = NULL; - ic->produced = mtext (); - ic->spot.x = ic->spot.y = 0; - ic->active = 1; - ic->plist = mplist (); - if ((*im->driver.create_ic) (ic) < 0) - { - M17N_OBJECT_UNREF (ic->preedit); - M17N_OBJECT_UNREF (ic->produced); - M17N_OBJECT_UNREF (ic->plist); - free (ic); - return NULL; - }; - - if (im->driver.callback_list) - { - minput__callback (ic, Minput_preedit_start); - minput__callback (ic, Minput_status_start); - minput__callback (ic, Minput_status_draw); - } - - return ic; -} - -/*=*/ - -/***en - @brief Destroy an input context. - - The minput_destroy_ic () function destroys the input context $IC, - which must have been created by minput_create_ic (). It calls - callback functions corresponding to #Minput_preedit_done, - #Minput_status_done, and #Mcandidate_done in this order. */ - -/***ja - @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë - - ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£¤³ - ¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê - ¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */ - -void -minput_destroy_ic (MInputContext *ic) -{ - if (ic->im->driver.callback_list) - { - minput__callback (ic, Minput_preedit_done); - minput__callback (ic, Minput_status_done); - minput__callback (ic, Minput_candidates_done); - } - (*ic->im->driver.destroy_ic) (ic); - M17N_OBJECT_UNREF (ic->preedit); - M17N_OBJECT_UNREF (ic->produced); - M17N_OBJECT_UNREF (ic->plist); - free (ic); -} - -/*=*/ - -/***en - @brief Filter an input key. - - The minput_filter () function filters input key $KEY according to - input context $IC, and calls callback functions corresponding to - #Minput_preedit_draw, #Minput_status_draw, and #Mcandidate_draw if - the preedit text, the status, and the current candidate are - changed respectively. - - @return - If $KEY is filtered out, this function returns 1. In that case, - the caller should discard the key. Otherwise, it returns 0, and - the caller should handle the key, for instance, by calling the - function minput_lookup () with the same $KEY. */ - -/***ja - @brief ÆþÎÏ¥­¡¼¤Î¥Õ¥£¥ë¥¿¥ê¥ó¥°¤ò¤¹¤ë - - ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥­¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Ë±þ - ¤¸¤Æ¥Õ¥£¥ë¥¿¥ê¥ó¥°¤¹¤ë¡£ - - ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ÎÆþÎϥ᥽¥Ã¥É¤¬ÆþÎÏ¥­¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ì¤Ð¡¢¤³ - ¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥­¡¼¤ò¼Î¤Æ¤ë¤Ù¤­¤Ç¤¢¤ë¡£ - ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤¬¡¢¤¿¤È¤¨¤ÐƱ¤¸ $KEY ¤Ç´Ø¿ô - minput_lookup () ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥­¡¼¤ò½èÍý¤¹¤ë¡£ - - @latexonly \IPAlabel{minput_filter} @endlatexonly -*/ - -int -minput_filter (MInputContext *ic, MSymbol key, void *arg) -{ - int ret; - - if (! ic - || ! ic->active) - return 0; - ret = (*ic->im->driver.filter) (ic, key, arg); - - if (ic->im->driver.callback_list) - { - if (ic->preedit_changed) - minput__callback (ic, Minput_preedit_draw); - if (ic->status_changed) - minput__callback (ic, Minput_status_draw); - if (ic->candidates_changed) - minput__callback (ic, Minput_candidates_draw); - ic->preedit_changed = ic->status_changed = ic->candidates_changed = 0; - } - - return ret; -} - -/*=*/ - -/***en - @brief Lookup a text produced in the input context. - - The minput_lookup () function looks up a text in the input context - $IC. $KEY must be the same one provided to the previous call of - minput_filter (). - - If a text was produced by the input method, it is concatenated - to M-text $MT. - - This function calls #MInputDriver::lookup. - - @return - If $KEY was correctly handled by the input method, this function - returns 0. Otherwise, returns -1, even in that case, some text - may be produced in $MT. */ - -/***ja - @brief ÆþÎϥ᥽¥Ã¥É¤¬ºî¤Ã¤¿¥Æ¥­¥¹¥È¤Î³ÍÆÀ - - ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥­¥¹¥È¤ò³ÍÆÀ¤¹ - ¤ë¡£$KEY ¤Ï´Ø¿ôminput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î - ¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ - - ¥Æ¥­¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢$IC->produced ¤ËÊÝ - »ý¤µ¤ì¤Æ¤¤¤ë¡£ - - ¤³¤Î´Ø¿ô¤Ï¡¢X ¥¦¥£¥ó¥É¥¦¤Î XLookupString () ¡¢ - XmbLookupString () ¡¢XwcLookupString () ¤ËÂбþ¤¹ - ¤ë¡£ - - @return - $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤­¤Æ¤¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤ò - ÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢¤³¤Î¾ì¹ç¤Ç¤â$IC->produced ¤Ë²¿¤é¤« - ¤Î¥Æ¥­¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£ - - @latexonly \IPAlabel{minput_lookup} @endlatexonly */ - -int -minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt) -{ - return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1); -} -/*=*/ - -/***en - @brief Set the spot of the input context. - - The minput_set_spot () function set the spot of input context $IC - to coordinate ($X, $Y) with the height $ASCENT and $DESCENT. - $FONTSIZE specfies the fontsize of a preedit text in 1/10 point. - The semantics of these values depend on the input driver. - - For instance, an input driver designed to work in CUI environment - may use $X and $Y as column and row numbers, and ignore $ASCENT - and $DESCENT. An input driver designed to work on a window system - may treat $X and $Y as pixel offsets relative to the origin of the - client window, and treat $ASCENT and $DESCENT as ascent and - descent pixels of a line at ($X . $Y). - - $MT and $POS is an M-text and a character position at the spot. - $MT may be NULL, in which case, the input method can't get - information about the text around the spot. */ - -/***ja - @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë - - ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂ - ɸ ($X, $Y)¤Ë ¡¢¹â¤µ $ASCENT¡¢$DESCENT ¤ÇÀßÄꤹ¤ë¡£¤³¤ì¤é¤ÎÃÍ¤Î°Õ - Ì£¤ÏÆþÎϥɥ饤¥Ð¤Ë°Í¸¤¹¤ë¡£ - - ¤¿¤È¤¨¤Ð CUI ´Ä¶­¤ÇÆ°ºî¤¹¤ëÆþÎϥɥ饤¥Ð¤Ï $X, $Y ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô - ¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT¡¢$DESCENT ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿ - ¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤÎÆþÎϥɥ饤¥Ð¤Ï $X,$Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É - ¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢ - $ASCENT ¤È $DESCENT ¤ò ($X . $Y) ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯ - ¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£ */ - -void -minput_set_spot (MInputContext *ic, int x, int y, - int ascent, int descent, int fontsize, - MText *mt, int pos) -{ - ic->spot.x = x; - ic->spot.y = y; - ic->spot.ascent = ascent; - ic->spot.descent = descent; - ic->spot.fontsize = fontsize; - ic->spot.mt = mt; - ic->spot.pos = pos; - if (ic->im->driver.callback_list) - minput__callback (ic, Minput_set_spot); -} -/*=*/ - -/***en - @brief Toggle input method. - - The minput_toggle () function toggles the input method associated - with the input context $IC. */ - -void -minput_toggle (MInputContext *ic) -{ - if (ic->im->driver.callback_list) - minput__callback (ic, Minput_toggle); - ic->active = ! ic->active; -} - - -/*** @} */ -/*=*/ -/*** @addtogroup m17nDebug */ -/*=*/ -/*** @{ */ -/*=*/ - -/***en - @brief Dump an input method - - The mdebug_dump_im () function prints the input method $IM in a - human readable way to the stderr. $INDENT specifies how many - columns to indent the lines but the first one. - - @return - This function returns $IM. */ - -MInputMethod * -mdebug_dump_im (MInputMethod *im, int indent) -{ - MInputMethodInfo *im_info = (MInputMethodInfo *) im->info; - char *prefix; - - prefix = (char *) alloca (indent + 1); - memset (prefix, 32, indent); - prefix[indent] = '\0'; - - fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language), - msymbol_name (im->name)); - mdebug_dump_mtext (im_info->title, 0, 0); - if (im->name != Mnil) - { - MPlist *state; - - MPLIST_DO (state, im_info->states) - { - fprintf (stderr, "\n%s ", prefix); - dump_im_state (MPLIST_VAL (state), indent + 2); - } - } - fprintf (stderr, ")"); - return im; -} - -/*** @} */ - -/* - Local Variables: - coding: euc-japan - End: -*/ diff --git a/src/input.h b/src/input.h deleted file mode 100644 index 1e00f0e..0000000 --- a/src/input.h +++ /dev/null @@ -1,84 +0,0 @@ -/* input.h -- header file for the input method module. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -#ifndef _M17N_INPUT_H_ -#define _M17N_INPUT_H_ - -typedef struct -{ - MText *title; - MPlist *states; - MPlist *macros; - MPlist *externals; -} MInputMethodInfo; - -typedef struct MIMState MIMState; - -typedef struct MIMMap MIMMap; - -typedef struct -{ - /** The current state. */ - MIMState *state; - - /** The current map. */ - MIMMap *map; - - /** Table of typed keys. */ - int size, inc, used; - MSymbol *keys; - - /** Index of the key handled firstly in the current state. */ - int state_key_head; - - /** Index of the key not yet handled. */ - int key_head; - - /** Saved M-text when entered in the current state. */ - MText *preedit_saved; - - /** The insertion position when shifted to the current state. */ - int state_pos; - - /** List of markers. */ - MPlist *markers; - - /* List of variables. */ - MPlist *vars; - - int key_unhandled; - - /** Used by minput_win_driver (input-win.c). */ - void *win_info; -} MInputContextInfo; - -#define MINPUT_KEY_SHIFT_MODIFIER (1 << 0) -#define MINPUT_KEY_CONTROL_MODIFIER (1 << 1) -#define MINPUT_KEY_META_MODIFIER (1 << 2) -#define MINPUT_KEY_ALT_MODIFIER (1 << 3) -#define MINPUT_KEY_SUPER_MODIFIER (1 << 4) -#define MINPUT_KEY_HYPER_MODIFIER (1 << 5) - -extern void minput__callback (MInputContext *ic, MSymbol command); -extern MSymbol minput__char_to_key (int c); - -#endif /* not _M17N_INPUT_H_ */ diff --git a/src/internal.h b/src/internal.h deleted file mode 100644 index 597abc8..0000000 --- a/src/internal.h +++ /dev/null @@ -1,605 +0,0 @@ -/* internal.h -- common header file for the internal CORE and SHELL APIs. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -#ifndef _M17N_INTERNAL_H_ -#define _M17N_INTERNAL_H_ - -/** @file internal.h - @brief a documentation for internal.h - - longer version of internal.h description -*/ - -extern int mdebug_hook (); - -/** Return with code RET while setting merror_code to ERR. */ - -#define MERROR(err, ret) \ - do { \ - merror_code = (err); \ - mdebug_hook (); \ - return (ret); \ - } while (0) - - -#define MERROR_GOTO(err, label) \ - do { \ - if ((err)) \ - merror_code = (err); \ - mdebug_hook (); \ - goto label; \ - } while (0) - - -#define MWARNING(err) \ - do { \ - mdebug_hook (); \ - goto warning; \ - } while (0) - - -#define M_CHECK_CHAR(c, ret) \ - if ((c) < 0 || (c) > MCHAR_MAX) \ - MERROR (MERROR_CHAR, (ret)); \ - else - - -/** Memory allocation stuffs. */ - -/* Call a handler function for memory full situation with argument - ERR. ERR must be one of enum MErrorCode. By default, the - handler function just calls exit () with argument ERR. */ - -#define MEMORY_FULL(err) \ - do { \ - (*m17n_memory_full_handler) (err); \ - exit (err); \ - } while (0) - - -/** The macro MTABLE_MALLOC () allocates memory (by malloc) for an - array of SIZE objects. The size of each object is determined by - the type of P. Then, it sets P to the allocated memory. ERR must - be one of enum MErrorCode. If the allocation fails, the macro - MEMORY_FULL () is called with argument ERR. */ - -#define MTABLE_MALLOC(p, size, err) \ - do { \ - int bytes = sizeof (*(p)) * (size); \ - if (! ((p) = (void *) malloc (bytes))) \ - MEMORY_FULL (err); \ - } while (0) - - -/** The macro MTABLE_CALLOC() is like the macro MTABLE_MALLOC but use - calloc instead of malloc, thus the allocated memory are zero - cleared. */ - -#define MTABLE_CALLOC(p, size, err) \ - do { \ - if (! ((p) = (void *) calloc (sizeof (*(p)), size))) \ - MEMORY_FULL (err); \ - } while (0) - - -/** The macro MTABLE_REALLOC () changes the size of memory block - pointed to by P to a size suitable for an array of SIZE objects. - The size of each object is determined by the type of P. ERR must - be one of enum MErrorCode. If the allocation fails, the macro - MEMORY_FULL () is called with argument ERR. */ - -#define MTABLE_REALLOC(p, size, err) \ - do { \ - if (! ((p) = (void *) realloc ((p), sizeof (*(p)) * (size)))) \ - MEMORY_FULL (err); \ - } while (0) - - -/** The macro MTABLE_ALLOCA () allocates memory (by alloca) for an - array of SIZE objects. The size of each object is determined by - the type of P. Then, it sets P to the allocated memory. ERR must - be one of enum MErrorCode. If the allocation fails, the macro - MEMORY_FULL () is called with argument ERR. */ - -#define MTABLE_ALLOCA(p, size, err) \ - do { \ - int bytes = sizeof (*(p)) * (size); \ - if (! ((p) = (void *) alloca (bytes))) \ - MEMORY_FULL (err); \ - memset ((p), 0, bytes); \ - } while (0) - - -/** short description of MSTRUCT_MALLOC */ -/** The macro MSTRUCT_MALLOC () allocates memory (by malloc) for an - object whose size is determined by the type of P, and sets P to - the allocated memory. ERR must be one of enum MErrorCode. If - the allocation fails, the macro MEMORY_FULL () is called with - argument ERR. */ - -#define MSTRUCT_MALLOC(p, err) \ - do { \ - if (! ((p) = (void *) malloc (sizeof (*(p))))) \ - MEMORY_FULL (err); \ - } while (0) - - -#define MSTRUCT_CALLOC(p, err) MTABLE_CALLOC ((p), 1, (err)) - - -/** Extendable array. */ - -#define MLIST_RESET(list) \ - ((list)->used = 0) - - -#define MLIST_INIT1(list, mem, increment) \ - do { \ - (list)->size = (list)->used = 0; \ - (list)->inc = (increment); \ - (list)->mem = NULL; \ - } while (0) - - -#define MLIST_APPEND1(list, mem, elt, err) \ - do { \ - if ((list)->inc <= 0) \ - mdebug_hook (); \ - if ((list)->size == (list)->used) \ - { \ - (list)->size += (list)->inc; \ - MTABLE_REALLOC ((list)->mem, (list)->size, (err)); \ - } \ - (list)->mem[(list)->used++] = (elt); \ - } while (0) - - -#define MLIST_PREPEND1(list, mem, elt, err) \ - do { \ - if ((list)->inc <= 0) \ - mdebug_hook (); \ - if ((list)->size == (list)->used) \ - { \ - (list)->size += (list)->inc; \ - MTABLE_REALLOC ((list)->mem, (list)->size, (err)); \ - } \ - memmove ((list)->mem + 1, (list)->mem, \ - sizeof *((list)->mem) * ((list)->used)); \ - (list)->mem[0] = (elt); \ - (list)->used++; \ - } while (0) - - -#define MLIST_INSERT1(list, mem, idx, len, err) \ - do { \ - while ((list)->used + (len) > (list)->size) \ - { \ - (list)->size += (list)->inc; \ - MTABLE_REALLOC ((list)->mem, (list)->size, (err)); \ - } \ - memmove ((list)->mem + ((idx) + (len)), (list)->mem + (idx), \ - (sizeof *((list)->mem)) * ((list)->used - (idx))); \ - (list)->used += (len); \ - } while (0) - - -#define MLIST_DELETE1(list, mem, idx, len) \ - do { \ - memmove ((list)->mem + (idx), (list)->mem + (idx) + (len), \ - (sizeof *((list)->mem)) * ((list)->used - (idx) - (len))); \ - (list)->used -= (len); \ - } while (0) - - -#define MLIST_COPY1(list0, list1, mem, err) \ - do { \ - (list0)->size = (list0)->used = (list1)->used; \ - (list0)->inc = 1; \ - MTABLE_MALLOC ((list0)->mem, (list0)->used, (err)); \ - memcpy ((list0)->mem, (list1)->mem, \ - (sizeof (list0)->mem) * (list0)->used); \ - } while (0) - - -#define MLIST_FREE1(list, mem) \ - if ((list)->size) \ - { \ - free ((list)->mem); \ - (list)->mem = NULL; \ - (list)->size = (list)->used = 0; \ - } \ - else - - - -typedef struct -{ - void (*freer) (void *); - int size, inc, used; - unsigned *counts; -} M17NObjectRecord; - -typedef struct -{ - /**en Reference count of the object. */ - unsigned ref_count : 16; - - unsigned ref_count_extended : 1; - - /**en A flag bit used for various perpose. */ - unsigned flag : 15; - - union { - /**en If is zero, a function to free the - object. */ - void (*freer) (void *); - /**en If is nonzero, a pointer to the - struct M17NObjectRecord. */ - M17NObjectRecord *record; - } u; -} M17NObject; - - -/** Allocate a managed object OBJECT which has freer FREE_FUNC. */ - -#define M17N_OBJECT(object, free_func, err) \ - do { \ - MSTRUCT_CALLOC ((object), (err)); \ - ((M17NObject *) (object))->ref_count = 1; \ - ((M17NObject *) (object))->u.freer = free_func; \ - } while (0) - - -/**en Increment the reference count of OBJECT if the count is not - 0. */ - -#define M17N_OBJECT_REF(object) \ - do { \ - if (((M17NObject *) (object))->ref_count_extended) \ - m17n_object_ref (object); \ - else if (((M17NObject *) (object))->ref_count > 0) \ - { \ - ((M17NObject *) (object))->ref_count++; \ - if (! ((M17NObject *) (object))->ref_count) \ - { \ - ((M17NObject *) (object))->ref_count--; \ - m17n_object_ref (object); \ - } \ - } \ - } while (0) - - -#define M17N_OBJECT_REF_NTIMES(object, n) \ - do { \ - int i; \ - \ - if (((M17NObject *) (object))->ref_count_extended) \ - for (i = 0; i < n; i++) \ - m17n_object_ref (object); \ - else if (((M17NObject *) (object))->ref_count > 0) \ - { \ - int orig_ref_count = ((M17NObject *) (object))->ref_count; \ - \ - for (i = 0; i < n; i++) \ - if (! ++((M17NObject *) (object))->ref_count) \ - { \ - ((M17NObject *) (object))->ref_count = orig_ref_count; \ - for (i = 0; i < n; i++) \ - m17n_object_ref (object); \ - } \ - } \ - } while (0) - - -/***en Decrement the reference count of OBJECT if the count is greater - than 0. In that case, if the count becomes 0, free OBJECT. */ - -#define M17N_OBJECT_UNREF(object) \ - do { \ - if (object) \ - { \ - if (((M17NObject *) (object))->ref_count_extended) \ - m17n_object_unref (object); \ - else if (((M17NObject *) (object))->ref_count == 0) \ - break; \ - else if (((M17NObject *) (object))->ref_count > 1) \ - ((M17NObject *) (object))->ref_count--; \ - else \ - { \ - if (((M17NObject *) (object))->u.freer) \ - (((M17NObject *) (object))->u.freer) (object); \ - else \ - free (object); \ - } \ - } \ - } while (0) - - -typedef struct -{ - int count; - int size, inc, used; - void **objects; -} M17NObjectArray; - - -#define M17N_OBJECT_REGISTER(array, object) \ - if (mdebug__flag & MDEBUG_FINI) \ - { \ - if ((array).count == 0) \ - MLIST_INIT1 (&(array), objects, 256); \ - (array).count++; \ - MLIST_APPEND1 (&(array), objects, object, MERROR_OBJECT); \ - } \ - else - -#define M17N_OBJECT_UNREGISTER(array, object) \ - if (mdebug__flag & MDEBUG_FINI) \ - { \ - (array).count--; \ - if ((array).count >= 0) \ - { \ - int i = 0; \ - \ - while (i < (array).used && (array).objects[i] != object) i++; \ - if (i < (array).used) \ - (array).objects[i] = NULL; \ - else \ - mdebug_hook (); \ - } \ - else \ - mdebug_hook (); \ - } \ - else - - -extern void mdebug__report_object (char *name, M17NObjectArray *array); - - - -struct MTextPlist; - -struct MText -{ - M17NObject control; - - enum MTextFormat format; - - /**en Number of characters in the M-text */ - /**ja M-text Ãæ¤Îʸ»ú¿ô */ - int nchars; - - /**en Number of bytes used to represent the characters in the M-text. */ - /**ja M-text Ãæ¤Îʸ»ú¤òɽ¤ï¤¹¤¿¤á¤ËÍѤ¤¤é¤ì¤ë¥Ð¥¤¥È¿ô */ - int nbytes; - - /**en Character sequence of the M-text. */ - /**ja M-text Ãæ¤Îʸ»úÎó */ - unsigned char *data; - - /**en Number of bytes allocated for the @c data member. */ - /**ja ¥á¥ó¥Ð @c data ¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥Ð¥¤¥È¿ô */ - int allocated; - - /**en Pointer to the property list of the M-text. */ - /**ja M-text ¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿ */ - struct MTextPlist *plist; - - /**en Caches of the character position and the corresponding byte position. */ - /**ja ʸ»ú°ÌÃÖ¤ª¤è¤ÓÂбþ¤¹¤ë¥Ð¥¤¥È°ÌÃ֤Υ­¥ã¥Ã¥·¥å */ - int cache_char_pos, cache_byte_pos; -}; - -/** short description of M_CHECK_POS */ -/** longer description of M_CHECK_POS */ - -#define M_CHECK_POS(mt, pos, ret) \ - do { \ - if ((pos) < 0 || (pos) >= (mt)->nchars) \ - MERROR (MERROR_RANGE, (ret)); \ - } while (0) - - -/** short description of M_CHECK_POS_X */ -/** longer description of M_CHECK_POS_X */ - -#define M_CHECK_POS_X(mt, pos, ret) \ - do { \ - if ((pos) < 0 || (pos) > (mt)->nchars) \ - MERROR (MERROR_RANGE, (ret)); \ - } while (0) - - -/** short description of M_CHECK_RANGE */ -/** longer description of M_CHECK_RANGE */ - -#define M_CHECK_RANGE(mt, from, to, ret, ret2) \ - do { \ - if ((from) < 0 || (to) < (from) || (to) > (mt)->nchars) \ - MERROR (MERROR_RANGE, (ret)); \ - if ((from) == (to)) \ - return (ret2); \ - } while (0) - -#define M_CHECK_RANGE_X(mt, from, to, ret) \ - do { \ - if ((from) < 0 || (to) < (from) || (to) > (mt)->nchars) \ - MERROR (MERROR_RANGE, (ret)); \ - } while (0) - - -#define M_CHECK_POS_NCHARS(mt, pos, nchars, ret, ret2) \ - do { \ - int to = (pos) + (nchars); \ - \ - M_CHECK_RANGE ((mt), (pos), (to), (ret), (ret2)); \ - } while (0) - - -#define M_CHECK_READONLY(mt, ret) \ - do { \ - if ((mt)->allocated < 0) \ - MERROR (MERROR_MTEXT, (ret)); \ - } while (0) - -#define mtext_nchars(mt) ((mt)->nchars) - -#define mtext_nbytes(mt) ((mt)->nbytes) - -#define mtext_allocated(mt) ((mt)->allocated) - -#define mtext_reset(mt) (mtext_del ((mt), 0, (mt)->nchars)) - - - -enum MDebugMaskBit - { - MDEBUG_INIT = 0x01, - MDEBUG_FINI = 0x02, - MDEBUG_CHARSET = 0x04, - MDEBUG_CODING = 0x08, - MDEBUG_DATABASE = 0x10, - MDEBUG_FONT = 0x0100, - MDEBUG_FONT_FLT = 0x0200, - MDEBUG_FONT_OTF = 0x0400, - MDEBUG_INPUT = 0x0800, - MDEBUG_MAX - }; - -extern int mdebug__flag; -extern void mdebug__push_time (); -extern void mdebug__pop_time (); -extern void mdebug__print_time (); - -#define MDEBUG_PRINT(msg) \ - do { \ - if (mdebug__flag & mdebug_mask) \ - fprintf (stderr, (msg)); \ - } while (0) - -#define MDEBUG_PRINT1(fmt, arg) \ - do { \ - if (mdebug__flag & mdebug_mask) \ - fprintf (stderr, (fmt), (arg)); \ - } while (0) - -#define MDEBUG_PRINT2(fmt, arg1, arg2) \ - do { \ - if (mdebug__flag & mdebug_mask) \ - fprintf (stderr, (fmt), (arg1), (arg2)); \ - } while (0) - -#define MDEBUG_PRINT3(fmt, arg1, arg2, arg3) \ - do { \ - if (mdebug__flag & mdebug_mask) \ - fprintf (stderr, (fmt), (arg1), (arg2), (arg3)); \ - } while (0) - -#define MDEBUG_PRINT4(fmt, arg1, arg2, arg3, arg4) \ - do { \ - if (mdebug__flag & mdebug_mask) \ - fprintf (stderr, (fmt), (arg1), (arg2), (arg3), (arg4)); \ - } while (0) - - -#define MDEBUG_PUSH_TIME() \ - do { \ - if (mdebug__flag & mdebug_mask) \ - mdebug__push_time (); \ - } while (0) - - -#define MDEBUG_POP_TIME() \ - do { \ - if (mdebug__flag & mdebug_mask) \ - mdebug__pop_time (); \ - } while (0) - - -#define MDEBUG_PRINT_TIME(tag, ARG_LIST) \ - do { \ - if (mdebug__flag & mdebug_mask) \ - { \ - fprintf (stderr, " [%s] ", tag); \ - mdebug__print_time (); \ - fprintf ARG_LIST; \ - fprintf (stderr, "\n"); \ - } \ - } while (0) - - -#define SWAP_16(c) (((c) >> 8) | (((c) & 0xFF) << 8)) - -#define SWAP_32(c) \ - (((c) >> 24) | (((c) >> 8) & 0xFF00) \ - | (((c) & 0xFF00) << 8) | (((c) & 0xFF) << 24)) - - -extern void *(*mdatabase__finder) (MSymbol tag1, MSymbol tag2, - MSymbol tag3, MSymbol tag4); -extern void *(*mdatabase__loader) (void *); - -/* Initialize/finalize function. */ - -extern int msymbol__init (); -extern void msymbol__fini (); - -extern int mplist__init (); -extern void mplist__fini (); - -extern int mtext__init (); -extern void mtext__fini (); - -extern int mtext__prop_init (); -extern void mtext__prop_fini (); - -extern int mchartable__init (); -extern void mchartable__fini (); - -extern int mcharset__init (); -extern void mcharset__fini (); - -extern int mcoding__init (); -extern void mcoding__fini (); - -extern int mdatabase__init (void); -extern void mdatabase__fini (void); - -extern int mchar__init (); -extern void mchar__fini (); - -extern int mlang__init (); -extern void mlang__fini (); - -extern int mlocale__init (); -extern void mlocale__fini (); - -extern int minput__init (); -extern void minput__fini (); - -#endif /* _M17N_INTERNAL_H_ */ - -/* - Local Variables: - coding: euc-japan - End: -*/ diff --git a/src/language.c b/src/language.c deleted file mode 100644 index 02bc214..0000000 --- a/src/language.c +++ /dev/null @@ -1,250 +0,0 @@ -/* language.c -- language module. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -#include -#include -#include "m17n.h" -#include "m17n-misc.h" -#include "internal.h" -#include "language.h" -#include "symbol.h" - - -/* Internal API */ - -int -mlang__init () -{ - /* ISO 639 */ - struct { - char *name, *fullname; - } lang_rec[] = - { {"ab", "Abkhazian"}, - {"aa", "Afar"}, - {"af", "Afrikaans"}, - {"sq", "Albanian"}, - {"am", "Amharic"}, - {"ar", "Arabic"}, - {"hy", "Armenian"}, - {"as", "Assamese"}, - {"ay", "Aymara"}, - {"az", "Azerbaijani"}, - {"ba", "Bashkir"}, - {"eu", "Basque"}, - {"bn", "Bengali"}, /* Bangla */ - {"dz", "Bhutani"}, - {"bh", "Bihari"}, - {"bi", "Bislama"}, - {"br", "Breton"}, - {"bg", "Bulgarian"}, - {"my", "Burmese"}, - {"be", "Byelorussian"}, /* Belarusian */ - {"km", "Cambodian"}, /* Khmer */ - {"ca", "Catalan"}, -#if 0 - {"??", "Cherokee"}, - {"??", "Chewa"}, -#endif - {"zh", "Chinese"}, - {"co", "Corsican"}, - {"hr", "Croatian"}, - {"cs", "Czech"}, - {"da", "Danish"}, -#if 0 - {"??", "Divehi"}, -#endif - {"nl", "Dutch"}, -#if 0 - {"??", "Edo"}, -#endif - {"en", "English"}, - {"eo", "Esperanto"}, - {"et", "Estonian"}, - {"fo", "Faeroese"}, - {"fa", "Farsi"}, - {"fj", "Fiji"}, - {"fi", "Finnish"}, -#if 0 - {"??", "Flemish"}, -#endif - {"fr", "French"}, - {"fy", "Frisian"}, -#if 0 - {"??", "Fulfulde"}, -#endif - {"gl", "Galician"}, - {"gd", "Gaelic(Scottish)"}, /* Scottish */ - {"gv", "Gaelic(Manx)"}, /* Manx */ - {"ka", "Georgian"}, - {"de", "German"}, - {"el", "Greek"}, - {"kl", "Greenlandic"}, - {"gn", "Guarani"}, - {"gu", "Gujarati"}, - {"ha", "Hausa"}, -#if 0 - {"??", "Hawaiian"}, - {"iw", "Hebrew"}, -#endif - {"he", "Hebrew"}, - {"hi", "Hindi"}, - {"hu", "Hungarian"}, -#if 0 - {"??", "Ibibio"}, -#endif - {"is", "Icelandic"}, -#if 0 - {"??", "Igbo"}, - {"in", "Indonesian"}, -#endif - {"id", "Indonesian"}, -#if 0 - {"ia", "Interlingua"}, - {"ie", "Interlingue"}, -#endif - {"iu", "Inuktitut"}, - {"ik", "Inupiak"}, - {"ga", "Irish"}, - {"it", "Italian"}, - {"ja", "Japanese"}, - {"jw", "Javanese"}, - {"kn", "Kannada"}, -#if 0 - {"??", "Kanuri"}, -#endif - {"ks", "Kashmiri"}, - {"kk", "Kazakh"}, - {"rw", "Kinyarwanda"}, /* Ruanda */ - {"ky", "Kirghiz"}, - {"rn", "Kirundi"}, /* Rundi */ - {"ko", "Korean"}, - {"ku", "Kurdish"}, - {"lo", "Laothian"}, - {"la", "Latin"}, - {"lv", "Latvian"}, /* Lettish */ - {"ln", "Lingala"}, - {"lt", "Lithuanian"}, - {"mk", "Macedonian"}, - {"mg", "Malagasy"}, - {"ms", "Malay"}, - {"ml", "Malayalam"}, -#if 0 - {"??", "Manipuri"}, -#endif - {"mt", "Maltese"}, - {"mi", "Maori"}, - {"mr", "Marathi"}, - {"mo", "Moldavian"}, - {"mn", "Mongolian"}, - {"na", "Nauru"}, - {"ne", "Nepali"}, - {"no", "Norwegian"}, - {"oc", "Occitan"}, - {"or", "Oriya"}, - {"om", "Oromo"}, /* Afan, Galla */ -#if 0 - {"??", "Papiamentu"}, -#endif - {"ps", "Pashto"}, /* Pushto */ - {"pl", "Polish"}, - {"pt", "Portuguese"}, - {"pa", "Punjabi"}, - {"qu", "Quechua"}, - {"rm", "Rhaeto-Romance"}, - {"ro", "Romanian"}, - {"ru", "Russian"}, -#if 0 - {"??", "Sami"}, /* Lappish */ -#endif - {"sm", "Samoan"}, - {"sg", "Sangro"}, - {"sa", "Sanskrit"}, - {"sr", "Serbian"}, - {"sh", "Serbo-Croatian"}, - {"st", "Sesotho"}, - {"tn", "Setswana"}, - {"sn", "Shona"}, - {"sd", "Sindhi"}, - {"si", "Sinhalese"}, - {"ss", "Siswati"}, - {"sk", "Slovak"}, - {"sl", "Slovenian"}, - {"so", "Somali"}, - {"es", "Spanish"}, - {"su", "Sundanese"}, - {"sw", "Swahili"}, /* Kiswahili */ - {"sv", "Swedish"}, -#if 0 - {"??", "Syriac"}, -#endif - {"tl", "Tagalog"}, - {"tg", "Tajik"}, -#if 0 - {"??", "Tamazight"}, -#endif - {"ta", "Tamil"}, - {"tt", "Tatar"}, - {"te", "Telugu"}, - {"th", "Thai"}, - {"bo", "Tibetan"}, - {"ti", "Tigrinya"}, - {"to", "Tonga"}, - {"ts", "Tsonga"}, - {"tr", "Turkish"}, - {"tk", "Turkmen"}, - {"tw", "Twi"}, - {"ug", "Uighur"}, - {"uk", "Ukrainian"}, - {"ur", "Urdu"}, - {"uz", "Uzbek"}, -#if 0 - {"??", "Venda"}, -#endif - {"vi", "Vietnamese"}, - {"vo", "Volapuk"}, - {"cy", "Welsh"}, - {"wo", "Wolof"}, - {"xh", "Xhosa"}, -#if 0 - {"??", "Yi"}, - {"ji", "Yiddish"}, -#endif - {"yi", "Yiddish"}, - {"yo", "Yoruba"}, - {"zu", "Zulu"} }; - int i; - - Mlanguage = msymbol ("language"); - msymbol_put (Mlanguage, Mtext_prop_serializer, - (void *) msymbol__serializer); - msymbol_put (Mlanguage, Mtext_prop_deserializer, - (void *) msymbol__deserializer); - for (i = 0; i < ((sizeof lang_rec) / (sizeof lang_rec[0])); i++) - msymbol_put (msymbol (lang_rec[i].name), Mlanguage, - msymbol (lang_rec[i].fullname)); - return 0; -} - -void -mlang__fini (void) -{ -} diff --git a/src/language.h b/src/language.h deleted file mode 100644 index 3e495d1..0000000 --- a/src/language.h +++ /dev/null @@ -1,26 +0,0 @@ -/* language.h -- header file for the language module. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -#ifndef _M17N_LANGUAGE_H_ -#define _M17N_LANGUAGE_H_ - -#endif /* _M17N_LANGUAGE_H_ */ diff --git a/src/linkcore.c b/src/linkcore.c deleted file mode 100644 index 4a5da33..0000000 --- a/src/linkcore.c +++ /dev/null @@ -1,32 +0,0 @@ -/* linkcore.c -- test program for linking with m17n-core.so. - Copyright (C) 2003 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - -This file is part of the m17n library. - -The m17n library is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2, or (at -your option) any later version. - -The m17n library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with the m17n library; see the file COPYING. If not, write to -the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include -#include "m17n-core.h" - -int -main () -{ - M17N_INIT (); - M17N_FINI (); - exit (0); -} diff --git a/src/linkgui.c b/src/linkgui.c deleted file mode 100644 index 5b70689..0000000 --- a/src/linkgui.c +++ /dev/null @@ -1,33 +0,0 @@ -/* linkgui.c -- test program for linking with m17n-X.so. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -#include -#include "m17n-gui.h" -#include "m17n-misc.h" - -int -main () -{ - M17N_INIT (); - M17N_FINI (); - exit (0); -} diff --git a/src/linkshell.c b/src/linkshell.c deleted file mode 100644 index 7190e4d..0000000 --- a/src/linkshell.c +++ /dev/null @@ -1,32 +0,0 @@ -/* linkshell.c -- test program for linking with m17n.so. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -#include -#include - -int -main () -{ - M17N_INIT (); - M17N_FINI (); - exit (0); -} diff --git a/src/locale.c b/src/locale.c deleted file mode 100644 index a20a23c..0000000 --- a/src/locale.c +++ /dev/null @@ -1,610 +0,0 @@ -/* locale.c -- locale module. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -/***en - @addtogroup m17nLocale - @brief Locale objects and API for them - - The m17n library represents locale related information as objects - of type #MLocale. */ - -/***ja - @addtogroup m17nLocale - @brief ¥í¥±¡¼¥ë¥ª¥Ö¥¸¥§¥¯¥È¤È¤½¤ì¤Ë´Ø¤¹¤ë API - - m17n ¥é¥¤¥Ö¥é¥ê¤Ï¥í¥±¡¼¥ë´ØÏ¢¾ðÊó¤ò #MLocale ·¿¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ç - ɽ¸½¤¹¤ë¡£ */ - -/*=*/ - -#if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE) -/*** @addtogroup m17nInternal - @{ */ - -#define _GNU_SOURCE - -#include -#include -#include -#include -#include -#ifdef HAVE_LANGINFO_H -#include -#endif -#include - -#include "m17n.h" -#include "m17n-misc.h" -#include "internal.h" -#include "symbol.h" -#include "coding.h" -#include "textprop.h" -#include "mlocale.h" - -static MSymbol M_locale; -static MSymbol M_xfrm; - - -/** Structure of locales. */ - -struct MLocale -{ - M17NObject control; - MSymbol name; - MSymbol language; - MSymbol territory; - MSymbol modifier; - MSymbol codeset; - MSymbol coding; -}; - - -/** The current locales of each category. */ -MLocale *mlocale__collate, *mlocale__ctype; -MLocale *mlocale__messages, *mlocale__time; - -/* These are currently not used. */ -#if 0 -MLocale *mlocale_monetary, *mlocale_numeric, ; -#endif - -/** Parse locale name NAME and return a newly created MLocale object. - If the locale is not supported by the system, return NULL. */ - -static MLocale * -make_locale (const char *name) -{ - char *current, *new, *str; - int len; - MLocale *locale; - char c; - - str = setlocale (LC_CTYPE, NULL); - len = strlen (str) + 1; - current = alloca (len); - memcpy (current, str, len); - - if (! (new = setlocale (LC_CTYPE, name))) - return NULL; - - - M17N_OBJECT (locale, NULL, MERROR_LOCALE); - locale->name = msymbol (new); - msymbol_put (locale->name, M_locale, (void *) locale); - M17N_OBJECT_UNREF (locale); - - len = strlen (new) + 1; - str = alloca (len); - memcpy (str, new, len); - - c = '\0'; - while (1) - { - char c1; - int i; - - for (i = 0; str[i]; i++) - if (str[i] == '_' || str[i] == '.' || str[i] == '@') - break; - c1 = str[i]; - str[i] = '\0'; - if (c == '\0') - /* The first field is for language. */ - locale->language = msymbol (name); - else if (c == '_') - /* The field following '_' is for territory. */ - locale->territory = msymbol (name); - else if (c == '.') - /* The field following '.' is for codeset. */ - locale->codeset = msymbol (name); - else - /* The other field is for modifier. */ - locale->modifier = msymbol (name); - if (! c1) - break; - c = c1; - name += i + 1; - } - -#ifdef HAVE_NL_LANGINFO -#ifdef CODESET - /* If we can use nl_langinfo () to retrieve a codeset name, respect - it over the codeset name extracted from the locale name. */ - locale->codeset = msymbol (nl_langinfo (CODESET)); -#endif -#endif - - /* If the locale name specifies a codeset, get the corresponding - coding system. */ - if (locale->codeset != Mnil) - { - locale->coding = mconv_resolve_coding (locale->codeset); - if (locale->coding == Mnil) - locale->coding = Mcoding_us_ascii; - } - else - locale->coding = Mcoding_us_ascii; - - setlocale (LC_CTYPE, current); - return locale; -} - - -/** Decode the byte sequence at BUF of length SIZE bytes by the coding - system associated with LOCALE, and return a generated M-text. */ - -static MText * -decode_locale (unsigned char *buf, int size, MLocale *locale) -{ - return mconv_decode_buffer (locale->coding, buf, size); -} - - -/** Encode the M-text MT by the coding system associated with LOCALE, - and store the resulting bytes in the memory area at BUF of *SIZE - bytes. If the area is too short, allocate a new and wider area. - Store the length of the generated bytes in the place pointed by - SIZE, and return the address of those bytes. */ - -static unsigned char * -encode_locale (MText *mt, unsigned char *buf, int *size, MLocale *locale) -{ - int nbytes = mconv_encode_buffer (locale->coding, mt, buf, *size - 1); - - if (nbytes < 0) - { - buf = NULL; - *size *= 2; - do { - MTABLE_REALLOC (buf, *size, MERROR_LOCALE); - nbytes = mconv_encode_buffer (mlocale__ctype->coding, mt, buf, - *size - 1); - } while (nbytes < 0); - } - buf[nbytes] = '\0'; - *size = nbytes; - return buf; -} - - -/** Structure of transformed strings. The function mtext_coll () - caches this object in an M-text as a text property. */ - -typedef struct { - /* Common header for a managed object. */ - M17NObject control; - - /* Locale corresponding to . */ - MLocale *locale; - - /** Result of strxfrm. */ - char *str; -} MXfrm; - - -static void -free_xfrm (void *object) -{ - MXfrm *xfrm = (MXfrm *) object; - - M17N_OBJECT_UNREF (xfrm->locale); - free (xfrm->str); -} - -static char * -get_xfrm (MText *mt) -{ - MTextProperty *prop = mtext_get_property (mt, 0, M_xfrm); - MXfrm *xfrm; - int size; - unsigned char *buf, *newbuf; - int request; - - if (prop) - { - if (prop->end == mt->nchars) - { - xfrm = (MXfrm *) prop->val; - if (xfrm->locale == mlocale__ctype) - return xfrm->str; - } - mtext_detach_property (prop); - } - - size = mt->nbytes; - buf = alloca (size); - newbuf = encode_locale (mt, buf, &size, mlocale__ctype); - M17N_OBJECT (xfrm, free_xfrm, MERROR_MTEXT); - xfrm->str = malloc (size); - request = strxfrm (xfrm->str, (char *) newbuf, size); - if (request >= size) - { - xfrm->str = realloc (xfrm->str, request); - strxfrm (xfrm->str, (char *) newbuf, size); - } - if (buf != newbuf) - free (newbuf); - prop = mtext_property (M_xfrm, xfrm, MTEXTPROP_VOLATILE_WEAK); - mtext_attach_property (mt, 0, mt->nchars, prop); - M17N_OBJECT_UNREF (prop); - return xfrm->str; -} - - -/* Internal API */ - -int -mlocale__init () -{ - M_locale = msymbol_as_managing_key (" locale"); - - Mlanguage = msymbol ("language"); - Mterritory = msymbol ("territory"); - Mcodeset = msymbol ("codeset"); - - mlocale__collate = mlocale_set (LC_COLLATE, NULL); - M17N_OBJECT_REF (mlocale__collate); - mlocale__ctype = mlocale_set (LC_CTYPE, NULL); - M17N_OBJECT_REF (mlocale__ctype); - mlocale__messages = mlocale_set (LC_MESSAGES, NULL); - M17N_OBJECT_REF (mlocale__messages); - mlocale__time = mlocale_set (LC_TIME, NULL); - M17N_OBJECT_REF (mlocale__time); - - M_xfrm = msymbol_as_managing_key (" xfrm"); - return 0; -} - -void -mlocale__fini () -{ - M17N_OBJECT_UNREF (mlocale__collate); - M17N_OBJECT_UNREF (mlocale__ctype); - M17N_OBJECT_UNREF (mlocale__messages); - M17N_OBJECT_UNREF (mlocale__time); -} - -/*** @} */ -#endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */ - - -/* External API */ -/*** @addtogroup m17nLocale */ -/*** @{ */ - -/*=*/ -/***en The symbol whose name is "language". */ -/***ja ¥·¥ó¥Ü¥ë "language" */ -MSymbol Mlanguage; - -/*=*/ -/***en The symbol whose name is "territory". */ -/***ja ¥·¥ó¥Ü¥ë "territory" */ -MSymbol Mterritory; - -/*=*/ -/***en The symbol whose name is "modifier". */ -/***ja ¥·¥ó¥Ü¥ë "modifier" */ -MSymbol Mmodifier; - -/*=*/ -/***en The symbol whose name is "codeset". */ -/***ja ¥·¥ó¥Ü¥ë "codeset" */ -MSymbol Mcodeset; - -/*=*/ - -/***en - @brief Set the current locale. - - The mlocale_set () function sets or query a part of the current - locale. The part is specified by $CATEGORY which must be a valid - first argument to setlocale (). - - If $LOCALE is not NULL, the locale of the specified part is set to - $LOCALE. If $LOCALE is not supported by the system, the current - locale is not changed. - - If $LOCALE is NULL, the current locale of the specified part is - queried. - - @return - If the call is successful, mlocale_set () returns an opaque locale - object that corresponds to the locale. The name of the locale can - be acquired by the function mlocale_get_prop (). - - Otherwise, it returns NULL. */ - -/***ja - @brief ¸½ºß¤Î¥í¥±¡¼¥ë¤òÀßÄꤹ¤ë. - - ´Ø¿ô mlocale_set () ¤Ï $LOCALE_NAME ¤ò¸½ºß¤Î¥í¥±¡¼¥ë¤È¤¹¤ë¡£¤³¤Î´Ø - ¿ô¤Ï¥·¥¹¥Æ¥à´Ø¿ô setlocale () ¤ò¸Æ¤Ó¡¢³°ÉôÊÑ¿ô @c - mlocale_current ¤òÀßÄꤹ¤ë¡£ - - @return - ¥·¥¹¥Æ¥à¤¬ $LOCALE_NAME ¤ò¥µ¥Ý¡¼¥È¤¹¤ë¤Ê¤é¤Ð mlocale_set () ¤Ï 0 - ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼ - ¥É¤òÀßÄꤹ¤ë¡£ */ - -/*** - @errors - @c MERROR_LOCALE */ - -MLocale * -mlocale_set (int category, const char *name) -{ - char *new; - MLocale *locale; - - new = setlocale (category, name); - if (! new) - return NULL; - - locale = (MLocale *) msymbol_get (msymbol (new), M_locale); - if (! locale) - locale = make_locale (new); - if (! locale) - return NULL; - if (name && (category == LC_ALL || category == LC_COLLATE)) - { - M17N_OBJECT_UNREF (mlocale__collate); - M17N_OBJECT_REF (locale); - mlocale__collate = locale; - } - else if (name && (category == LC_ALL || category == LC_CTYPE)) - { - M17N_OBJECT_UNREF (mlocale__ctype); - M17N_OBJECT_REF (locale); - mlocale__ctype = locale; - } - if (name && (category == LC_ALL || category == LC_MESSAGES)) - { - M17N_OBJECT_UNREF (mlocale__messages); - M17N_OBJECT_REF (locale); - mlocale__messages = locale; - } - if (name && (category == LC_ALL || category == LC_TIME)) - { - M17N_OBJECT_UNREF (mlocale__time); - M17N_OBJECT_REF (locale); - mlocale__time = locale; - } - return locale; -} - -/*=*/ - -/***en - @brief Get the value of a locale property. - - The mlocale_get_prop () function returns the value of a property - $KEY of local $LOCALE. $KEY must be #Mname, #Mlanguage, - #Mterritory, #Mcodeset, #Mmodifier, or #Mcoding. */ - -/***ja - @brief ¥í¥±¡¼¥ë¤Î¥×¥í¥Ñ¥Æ¥£ÃͤòÆÀ¤ë - - ´Ø¿ô mlocale_get_prop () ¤Ï¡¢¥í¥±¡¼¥ë $LOCALE ¤Î $KEY ¥×¥í¥Ñ¥Æ¥£¤Î - ÃͤòÊÖ¤¹¡£ $KEY ¤Ï #Mname ¡¢ #Mlanguage ¡¢ #Mterritory ¡¢ - #Mcodeset ¡¢ #Mmodifier ¤â¤·¤¯¤Ï #Mcoding ¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê - ¤¤¡£ */ - -MSymbol -mlocale_get_prop (MLocale *locale, MSymbol key) -{ - if (key == Mcoding) - return locale->coding; - if (key == Mname) - return locale->name; - if (key == Mlanguage) - return locale->language; - if (key == Mterritory) - return locale->territory; - if (key == Mcodeset) - return locale->codeset; - if (key == Mmodifier) - return locale->modifier; - return Mnil; -} - -/*=*/ -/***en - @brief Format date and time - - The mtext_ftime () function formats the broken-down time $TM - according to the format specification $FORMAT and append the - result to the M-text $MT. The formating is done according to the - locale $LOCALE (if not NULL) or the current locale (LC_TIME). - - The meaning of the arguments $TM and $FORMAT are the same as those - of strftime (). - - @seealso - strftime () - -*/ - -int -mtext_ftime (MText *mt, const char *format, const struct tm *tm, - MLocale *locale) -{ - int bufsize; - unsigned char *buf; - size_t nbytes, nchars; - char *current_locale = NULL; - - if (locale) - { - char *str = setlocale (LC_TIME, NULL); - int len = strlen (str) + 1; - - current_locale = alloca (len); - memcpy (current_locale, str, len); - mlocale_set (LC_TIME, msymbol_name (locale->name)); - } - - bufsize = 1024; - while (1) - { - MTABLE_ALLOCA (buf, bufsize, MERROR_MTEXT); - buf[0] = 1; - nbytes = strftime ((char *) buf, bufsize, format, tm); - if (nbytes > 0 - || ! buf[0]) - break; - bufsize *= 2; - } - - if (nbytes > 0) - { - MText *work = decode_locale (buf, nbytes, mlocale__time); - - if (work) - { - nchars = work->nchars; - mtext_cat (mt, work); - M17N_OBJECT_UNREF (work); - } - else - nchars = 0; - } - else - nchars = 0; - - if (current_locale) - mlocale_set (LC_TIME, current_locale); - - return nchars; -} - -/*=*/ - -/***en - @brief Get an environment variable - - The mtext_getenv () function searches the environment list for a - string that matches the string pointed to by $NAME. - - If there is a match, the function decodes the value according to - the current locale (LC_CTYPE) into an M-text, and return that - M-text. - - If there is no match, the function returns NULL. */ - -MText * -mtext_getenv (const char *name) -{ - char *p = getenv (name); - - if (!p) - return NULL; - return decode_locale ((unsigned char *) p, strlen (p), mlocale__ctype); -} - -/*=*/ - -/***en - @brief Change or add an environment variable. - - The mtext_putenv () function adds or changed the value of - environment variables according to M-text $MT. It simply calls - the function putenv with an argument generated by encoding $MT - according to the current locale (LC_CTYPE). - - @return - This function returns zero on success, or -1 if an error - occurs. */ - -int -mtext_putenv (MText *mt) -{ - unsigned char buf[1024]; - int size = 1024; - unsigned char *newbuf; - int result; - - newbuf = encode_locale (mt, buf, &size, mlocale__ctype); - result = putenv ((char *) newbuf); - if (buf != newbuf) - free (newbuf); - return result; -} - -/*=*/ - -/***en - @brief Compare two M-texts using the current locale. - - The mtext_coll () function compares the two M-texts $MT1 and $MT2. - It returns an integer less than, equal to, or greater than zero if - $MT1 is found, respectively, to be less than, to match, or to be - greater than $MT2. The comparison is based on texts as - appropriate for the current locale (LC_COLLATE). - - This function makes use of information that is automatically - cached in the M-texts as a text property. So, the second call of - this function with $MT1 or $MT2 finishes faster than the first - call. */ - -int -mtext_coll (MText *mt1, MText *mt2) -{ - char *str1, *str2; - - if (mt1->nchars == 0) - return (mt2->nchars == 0 ? 0 : -1); - else if (mt2->nchars == 0) - return 1; - - str1 = get_xfrm (mt1); - str2 = get_xfrm (mt2); - return strcoll (str1, str2); -} - -/*** @} */ - -/* - Local Variables: - coding: euc-japan - End: -*/ diff --git a/src/m17n-X.c b/src/m17n-X.c deleted file mode 100644 index 974dd22..0000000 --- a/src/m17n-X.c +++ /dev/null @@ -1,2156 +0,0 @@ -/* m17n-X.c -- implementation of the GUI API on X Windows. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -#if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE) -/*** @addtogroup m17nInternal - @{ */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "m17n-gui.h" -#include "m17n-X.h" -#include "m17n-misc.h" -#include "internal.h" -#include "internal-gui.h" -#include "symbol.h" -#include "input.h" -#include "font.h" -#include "fontset.h" -#include "face.h" - -typedef struct -{ - /* Common header for the m17n object. */ - M17NObject control; - - Display *display; - - /* If nonzero, is opened by this library. Thus it should - be closed on freeing this structure. */ - int auto_display; - - /** List of available fonts on the display (except for iso8859-1 and - iso10646-1 fonts). Keys are font registries, values are - (MFontList *). */ - MPlist *font_registry_list; - - MPlist *iso8859_1_family_list; - - MPlist *iso10646_1_family_list; - - /* List of information about each font. Keys are font registries, - values are (MFontInfo *). */ - MPlist *realized_font_list; - - /** Modifier bit masks of the display. */ - int meta_mask; - int alt_mask; - int super_mask; - int hyper_mask; -} MDisplayInfo; - -/* Anchor of the chain of MDisplayInfo objects. */ -static MPlist *display_info_list; - -struct MWDevice -{ - /* Common header for the m17n object. */ - M17NObject control; - - MDisplayInfo *display_info; - - int screen_num; - - Drawable drawable; - - unsigned depth; - - Colormap cmap; - - unsigned long foreground, background; - - /** List of pointers to realized faces on the frame. */ - MPlist *realized_face_list; - - /** List of pointers to realized fontsets on the frame. */ - MPlist *realized_fontset_list; - -}; - -static MPlist *device_list; - -static MSymbol M_iso8859_1, M_iso10646_1; - -#define FRAME_DISPLAY(frame) (frame->device->display_info->display) -#define FRAME_SCREEN(frame) (frame->device->screen_num) - -static void -free_display_info (void *object) -{ - MDisplayInfo *disp_info = (MDisplayInfo *) object; - MPlist *plist; - - for (plist = disp_info->font_registry_list; - mplist_key (plist) != Mnil; plist = mplist_next (plist)) - { - MFontList *registry_list = mplist_value (plist); - - if (registry_list->fonts) - free (registry_list->fonts); - free (registry_list); - } - M17N_OBJECT_UNREF (disp_info->font_registry_list); - - for (plist = disp_info->iso8859_1_family_list; - mplist_key (plist) != Mnil; plist = mplist_next (plist)) - { - MFontList *family_list = mplist_value (plist); - - if (family_list->fonts) - free (family_list->fonts); - free (family_list); - } - M17N_OBJECT_UNREF (disp_info->iso8859_1_family_list); - - for (plist = disp_info->iso10646_1_family_list; - mplist_key (plist) != Mnil; plist = mplist_next (plist)) - { - MFontList *family_list = mplist_value (plist); - - if (family_list->fonts) - free (family_list->fonts); - free (family_list); - } - M17N_OBJECT_UNREF (disp_info->iso10646_1_family_list); - - for (plist = disp_info->realized_font_list; - mplist_key (plist) != Mnil; plist = mplist_next (plist)) - mfont__free_realized ((MRealizedFont *) mplist_value (plist)); - M17N_OBJECT_UNREF (disp_info->realized_font_list); - - if (disp_info->auto_display) - XCloseDisplay (disp_info->display); - - free (object); -} - -static void -free_device (void *object) -{ - MWDevice *device = (MWDevice *) object; - MPlist *plist; - - for (plist = device->realized_fontset_list; - mplist_key (plist) != Mnil; plist = mplist_next (plist)) - mfont__free_realized_fontset ((MRealizedFontset *) mplist_value (plist)); - M17N_OBJECT_UNREF (device->realized_fontset_list); - - for (plist = device->realized_face_list; - mplist_key (plist) != Mnil; plist = mplist_next (plist)) - mface__free_realized ((MRealizedFace *) mplist_value (plist)); - M17N_OBJECT_UNREF (device->realized_face_list); - - XFreePixmap (device->display_info->display, device->drawable); - M17N_OBJECT_UNREF (device->display_info); - free (object); -} - - -static void -find_modifier_bits (MDisplayInfo *disp_info) -{ - Display *display = disp_info->display; - XModifierKeymap *mods; - KeyCode meta_l = XKeysymToKeycode (display, XK_Meta_L); - KeyCode meta_r = XKeysymToKeycode (display, XK_Meta_R); - KeyCode alt_l = XKeysymToKeycode (display, XK_Alt_L); - KeyCode alt_r = XKeysymToKeycode (display, XK_Alt_R); - KeyCode super_l = XKeysymToKeycode (display, XK_Super_L); - KeyCode super_r = XKeysymToKeycode (display, XK_Super_R); - KeyCode hyper_l = XKeysymToKeycode (display, XK_Hyper_L); - KeyCode hyper_r = XKeysymToKeycode (display, XK_Hyper_R); - int i, j; - - mods = XGetModifierMapping (display); - /* We skip the first three sets for Shift, Lock, and Control. The - remaining sets are for Mod1, Mod2, Mod3, Mod4, and Mod5. */ - for (i = 3; i < 8; i++) - for (j = 0; j < mods->max_keypermod; j++) - { - KeyCode code = mods->modifiermap[i * mods->max_keypermod + j]; - - if (! code) - continue; - if (code == meta_l || code == meta_r) - disp_info->meta_mask |= (1 << i); - else if (code == alt_l || code == alt_r) - disp_info->alt_mask |= (1 << i); - else if (code == super_l || code == super_r) - disp_info->super_mask |= (1 << i); - else if (code == hyper_l || code == hyper_r) - disp_info->hyper_mask |= (1 << i); - } - - /* If meta keys are not in any modifier, use alt keys as meta - keys. */ - if (! disp_info->meta_mask) - { - disp_info->meta_mask = disp_info->alt_mask; - disp_info->alt_mask = 0; - } - /* If both meta and alt are assigned to the same modifier, give meta - keys priority. */ - if (disp_info->meta_mask & disp_info->alt_mask) - disp_info->alt_mask &= ~disp_info->meta_mask; - - XFreeModifiermap (mods); -} - -unsigned long -get_color (Display *display, Colormap cmap, - MSymbol color_name, MSymbol default_name, - unsigned long default_pixel) -{ - XColor exact_def; - - if (XParseColor (display, cmap, msymbol_name (color_name), &exact_def) - && XAllocColor (display, cmap, &exact_def)) - return exact_def.pixel; - - if (XParseColor (display, cmap, msymbol_name (default_name), &exact_def) - && XAllocColor (display, cmap, &exact_def)) - return exact_def.pixel; - - return default_pixel; -} - - -/** X font handler */ - -/** Indices to each field of split font name. */ - -enum xlfd_field_idx - { - XLFD_FOUNDRY, - XLFD_FAMILY, - XLFD_WEIGHT, - XLFD_SLANT, - XLFD_SWIDTH, - XLFD_ADSTYLE, - XLFD_PIXEL, - XLFD_POINT, - XLFD_RESX, - XLFD_RESY, - XLFD_SPACING, - XLFD_AVGWIDTH, - XLFD_REGISTRY, - XLFD_ENCODING, - /* anchor */ - XLFD_FIELD_MAX - }; - -/** Split the fontname NAME into each XLFD field destructively. Set - each element of the table pointed by PROPERTY_IDX to a pointer to - the corresponding font property name. Store the point size and - the resolution-Y of the font to the place pointed by POINT and - RESY respectively. - - If NAME does not contain all XLFD fields, the unspecified fields is - treated as wild cards. */ - -static int -split_font_name (char *name, char **field, - unsigned short *size, unsigned short *resy) -{ - int i; - char *p; - - for (i = 0, p = name; *p; p++) - { - *p = tolower (*p); - if (*p == '-' && i < XLFD_FIELD_MAX) - { - field[i] = p + 1; - if (i != XLFD_ENCODING) - *p = '\0'; - i++; - } - } - if (i < XLFD_REGISTRY) - return -1; - for (; i < XLFD_FIELD_MAX; i++) - field[i] = "*"; - - if (*(field[XLFD_RESY]) == '*') - *resy = 0; - else - *resy = atoi (field[XLFD_RESY]); - if (*(field[XLFD_PIXEL]) == '*') - { - if (*(field[XLFD_POINT]) != '*') - *size = atoi (field[XLFD_POINT]) * *resy / 72; - else - *size = 0; - } - else if (*(field[XLFD_PIXEL]) == '[') - { - /* The pixel size field specifies a transformation matrix of the - form "[A B C D]". The XLFD spec says that the scalar value N - for the pixel size is equivalent to D. */ - char *p0 = field[XLFD_PIXEL] + 1, *p1; - double d; - - for (i = 0; i < 4; i++, p0 = p1) - d = strtod (p0, &p1); - *size = d * 10; - } - else - *size = atoi (field[XLFD_PIXEL]) * 10; - if (*size == 0 && *(field[XLFD_POINT]) != '*') - { - *size = atoi (field[XLFD_POINT]); - if (*resy) - *size = *size * *resy / 72; - else - *size = *size * 100 / 72; - } - - return 0; -} - -static int -build_font_name (MFont *font, char *name, int limit) -{ - MSymbol prop[7]; - char *str[7]; - int len, i; - unsigned short size, resy; - - prop[0] = (MSymbol) mfont_get_prop (font, Mfoundry); - prop[1] = (MSymbol) mfont_get_prop (font, Mfamily); - prop[2] = (MSymbol) mfont_get_prop (font, Mweight); - prop[3] = (MSymbol) mfont_get_prop (font, Mstyle); - prop[4] = (MSymbol) mfont_get_prop (font, Mstretch); - prop[5] = (MSymbol) mfont_get_prop (font, Madstyle); - prop[6] = (MSymbol) mfont_get_prop (font, Mregistry); - for (len = 0, i = 0; i < 7; i++) - { - if (prop[i] != Mnil) - { - str[i] = msymbol_name (prop[i]); - len += strlen (str[i]); - } - else - { - str[i] = "*"; - len++; - } - } - if ((len - + 12 /* 12 dashes */ - + 3 /* 3 asterisks */ - + 30 /* 3 integers (each 10 digits) */ - + 1) /* '\0' terminal */ - > limit) - return -1; - - size = (int) mfont_get_prop (font, Msize); - if ((size % 10) < 5) - size /= 10; - else - size = size / 10 + 1; - resy = (int) mfont_get_prop (font, Mresolution); - - sprintf (name, "-%s-%s-%s-%s-%s-%s-%d-*-%d-%d-*-*-%s", - str[0], str[1], str[2], str[3], str[4], str[5], - size, resy, resy, str[6]); - return 0; -} - -static MFontList * -build_font_list (MFrame *frame, MSymbol family, MSymbol registry, - MPlist *plist) -{ - char pattern[1024]; - MFontList *font_list; - char **fontnames; - int nfonts; - int i, j; - - MSTRUCT_CALLOC (font_list, MERROR_WIN); - - if (family == Mnil) - { - sprintf (pattern, "-*-*-*-*-*-*-*-*-*-*-*-*-%s", - msymbol_name (registry)); - font_list->tag = registry; - } - else - { - sprintf (pattern, "-*-%s-*-*-*-*-*-*-*-*-*-*-%s", - msymbol_name (family), msymbol_name (registry)); - font_list->tag = family; - } - - fontnames = XListFonts (FRAME_DISPLAY (frame), pattern, 0x8000, &nfonts); - if (nfonts > 0) - { - MTABLE_MALLOC (font_list->fonts, nfonts, MERROR_WIN); - for (i = j = 0; i < nfonts; i++) - if (mwin__parse_font_name (fontnames[i], font_list->fonts + j) >= 0 - && (font_list->fonts[j].property[MFONT_SIZE] != 0 - || font_list->fonts[j].property[MFONT_RESY] == 0)) - { - font_list->fonts[j].property[MFONT_TYPE] = MFONT_TYPE_WIN + 1; - j++; - } - XFreeFontNames (fontnames); - font_list->nfonts = j; - } - mplist_add (plist, font_list->tag, font_list); - return (nfonts > 0 ? font_list : NULL); -} - - -static MRealizedFont *xfont_select (MFrame *, MFont *, MFont *, int); -static int xfont_open (MRealizedFont *); -static void xfont_close (MRealizedFont *); -static void xfont_find_metric (MRealizedFont *, MGlyph *); -static unsigned xfont_encode_char (MRealizedFont *, int, unsigned); -static void xfont_render (MDrawWindow, int, int, MGlyphString *, - MGlyph *, MGlyph *, int, MDrawRegion); - -MFontDriver xfont_driver = - { xfont_select, xfont_open, xfont_close, - xfont_find_metric, xfont_encode_char, xfont_render }; - -/* The X font driver function SELECT. */ - -static MRealizedFont * -xfont_select (MFrame *frame, MFont *spec, MFont *request, int limited_size) -{ - MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY); - MRealizedFont *rfont; - MFontList *font_list = NULL; - int i; - MFont *best_font; - int best_score, score; - - if (registry == Mnil - || ! strchr (MSYMBOL_NAME (registry), '-')) - return NULL; - - /* We handles iso8859-1 and iso10646-1 fonts specially because there - exists so many such fonts. */ - if (registry == M_iso8859_1 || registry == M_iso10646_1) - { - MPlist *family_list - = (registry == M_iso8859_1 - ? frame->device->display_info->iso8859_1_family_list - : frame->device->display_info->iso10646_1_family_list); - MSymbol family = FONT_PROPERTY (spec, MFONT_FAMILY); - - if (family != Mnil) - { - font_list = (MFontList *) mplist_get (family_list, family); - if (! font_list) - font_list = build_font_list (frame, family, registry, family_list); - } - if (! font_list) - { - family = FONT_PROPERTY (request, MFONT_FAMILY); - font_list = (MFontList *) mplist_get (family_list, family); - if (! font_list) - font_list = build_font_list (frame, family, registry, family_list); - } - } - if (! font_list) - { - MPlist *registry_list - = frame->device->display_info->font_registry_list; - - font_list = (MFontList *) mplist_get (registry_list, registry); - if (! font_list) - font_list = build_font_list (frame, Mnil, registry, registry_list); - } - if (! font_list) - return NULL; - - for (i = 0, best_score = -1, best_font = NULL; i < font_list->nfonts; i++) - if ((best_score = mfont__score (font_list->fonts + i, spec, request, - limited_size)) >= 0) - break; - if (best_score < 0) - return NULL; - best_font = font_list->fonts + i; - for (; best_score > 0 && i < font_list->nfonts ; i++) - { - score = mfont__score (font_list->fonts + i, spec, request, - limited_size); - if (score >= 0 && score < best_score) - { - best_font = font_list->fonts + i; - best_score = score; - } - } - - MSTRUCT_CALLOC (rfont, MERROR_WIN); - rfont->frame = frame; - rfont->spec = *spec; - rfont->request = *request; - rfont->font = *best_font; - if (best_font->property[MFONT_SIZE] == 0) - rfont->font.property[MFONT_SIZE] = request->property[MFONT_SIZE]; - rfont->score = best_score; - rfont->driver = &xfont_driver; - return rfont; -} - -typedef struct -{ - M17NObject control; - MFrame *frame; - XFontStruct *f; -} MXFontInfo; - -static void -close_xfont (void *object) -{ - MXFontInfo *xfont = (MXFontInfo *) object; - - if (xfont->f) - XFreeFont (FRAME_DISPLAY (xfont->frame), xfont->f); - free (object); -} - - -/* The X font driver function OPEN. */ - -static int -xfont_open (MRealizedFont *rfont) -{ - char name[1024]; - MXFontInfo *xfont; - MFrame *frame = rfont->frame; - int mdebug_mask = MDEBUG_FONT; - - /* This never fail to generate a valid fontname because open_spec - should correspond to a font available on the system. */ - build_font_name (&rfont->font, name, 1024); - M17N_OBJECT (xfont, close_xfont, MERROR_WIN); - rfont->info = xfont; - xfont->frame = frame; - xfont->f = XLoadQueryFont (FRAME_DISPLAY (frame), name); - if (! xfont->f) - { - rfont->status = -1; - MDEBUG_PRINT1 (" [XFONT] x %s\n", name); - return -1; - } - MDEBUG_PRINT1 (" [XFONT] o %s\n", name); - rfont->status = 1; - rfont->ascent = xfont->f->ascent; - rfont->descent = xfont->f->descent; - return 0; -} - - -/* The X font driver function CLOSE. */ - -static void -xfont_close (MRealizedFont *rfont) -{ - M17N_OBJECT_UNREF (rfont->info); -} - -/* The X font driver function FIND_METRIC. */ - -static void -xfont_find_metric (MRealizedFont *rfont, MGlyph *g) -{ - XCharStruct *pcm = NULL; - MXFontInfo *xfont = (MXFontInfo *) rfont->info; - XFontStruct *f = xfont->f; - int byte1, byte2; - - if (g->code == MCHAR_INVALID_CODE) - { - g->lbearing = f->max_bounds.lbearing; - g->rbearing = f->max_bounds.rbearing; - g->width = f->max_bounds.width; - g->ascent = f->ascent; - g->descent = f->descent; - return; - } - - byte1 = g->code >> 8; - byte2 = g->code & 0xFF; - - if (f->per_char != NULL) - { - if (f->min_byte1 == 0 && f->max_byte1 == 0) - { - if (byte1 == 0 - && byte2 >= f->min_char_or_byte2 - && byte2 <= f->max_char_or_byte2) - pcm = f->per_char + byte2 - f->min_char_or_byte2; - } - else - { - if (byte1 >= f->min_byte1 - && byte1 <= f->max_byte1 - && byte2 >= f->min_char_or_byte2 - && byte2 <= f->max_char_or_byte2) - { - pcm = (f->per_char - + ((f->max_char_or_byte2-f->min_char_or_byte2 + 1) - * (byte1 - f->min_byte1)) - + (byte2 - f->min_char_or_byte2)); - } - } - } - - if (pcm) - { - g->lbearing = pcm->lbearing; - g->rbearing = pcm->rbearing; - g->width = pcm->width; - g->ascent = pcm->ascent; - g->descent = pcm->descent; - } - else - { - /* If the per_char pointer is null, all glyphs between the first - and last character indexes inclusive have the same - information, as given by both min_bounds and max_bounds. */ - g->lbearing = 0; - g->rbearing = f->max_bounds.width; - g->width = f->max_bounds.width; - g->ascent = f->ascent; - g->descent = f->descent; - } -} - - -/* The X font driver function ENCODE_CHAR. */ - -static unsigned -xfont_encode_char (MRealizedFont *rfont, int c, unsigned code) -{ - MXFontInfo *xfont; - XFontStruct *f; - unsigned min_byte1, max_byte1, min_byte2, max_byte2; - int all_chars_exist; - - if (rfont->status < 0) - return -1; - if (rfont->status == 0) - { - if (xfont_open (rfont) < 0) - return -1; - } - xfont = (MXFontInfo *) rfont->info; - f = xfont->f; - all_chars_exist = (! f->per_char || f->all_chars_exist == True); - min_byte1 = f->min_byte1; - max_byte1 = f->max_byte1; - min_byte2 = f->min_char_or_byte2; - max_byte2 = f->max_char_or_byte2; - - if (min_byte1 == 0 && max_byte1 == 0) - { - XCharStruct *pcm; - - if (all_chars_exist) - return ((code >= min_byte2 && code <= max_byte2) - ? code : MCHAR_INVALID_CODE); - pcm = f->per_char + (code - min_byte2); - return ((pcm->width > 0 || pcm->rbearing != pcm->lbearing) - ? code : MCHAR_INVALID_CODE); - } - else - { - unsigned byte1 = code >> 8, byte2 = code & 0xFF; - XCharStruct *pcm; - - if (all_chars_exist) - return ((byte1 >= min_byte1 && byte1 <= max_byte1 - && byte2 >= min_byte2 && byte2 <= max_byte2) - ? code : MCHAR_INVALID_CODE); - pcm = f->per_char + ((byte1 - min_byte1) * (max_byte2 - min_byte2 + 1) - + (byte2 - min_byte2)); - return ((pcm->width > 0 || pcm->rbearing != pcm->lbearing) - ? code : MCHAR_INVALID_CODE); - } -} - -static GC -set_region (Display *display, MRealizedFace *rface, GC gc, MDrawRegion region) -{ - GC gc1; - XRectangle xrect; - - XClipBox (region, &xrect); - gc1 = ((GC *) rface->info)[MFACE_GC_SCRATCH]; - XCopyGC (display, gc, GCFont | GCForeground | GCBackground, gc1); - XSetRegion (display, gc1, region); - return gc1; -} - -/* The X font driver function RENDER. */ - -static void -xfont_render (MDrawWindow win, int x, int y, MGlyphString *gstring, - MGlyph *from, MGlyph *to, int reverse, MDrawRegion region) -{ - MRealizedFace *rface = from->rface; - Display *display; - XChar2b *code; - GC *gcs = rface->info; - GC gc = gcs[reverse ? MFACE_GC_INVERSE : MFACE_GC_NORMAL]; - MGlyph *g; - int i; - - if (from == to) - return; - - /* It is assured that the all glyphs in the current range use the - same realized face. */ - display = FRAME_DISPLAY (rface->frame); - - if (region) - gc = set_region (display, rface, gc, region); - - if (from->code == MCHAR_INVALID_CODE) - { - int x0 = x; - - for (; from < to; from++) - { - XDrawRectangle (display, (Window) win, gc, - x0, y - gstring->ascent + 1, from->width - 1, - gstring->ascent + gstring->descent - 2); - x0 += from->width; - } - return; - } - - code = (XChar2b *) alloca (sizeof (XChar2b) * (to - from)); - for (i = 0, g = from; g < to; i++, g++) - { - code[i].byte1 = g->code >> 8; - code[i].byte2 = g->code & 0xFF; - } - - g = from; - while (g < to) - { - if (g->type == GLYPH_PAD) - x += g++->width; - else if (g->type == GLYPH_SPACE) - for (; g < to && g->type == GLYPH_SPACE; g++) - x += g->width; - else if (! g->rface->rfont) - { - if ((g->c >= 0x200B && g->c <= 0x200F) - || (g->c >= 0x202A && g->c <= 0x202E)) - x += g++->width; - else - { - /* As a font is not found for this character, draw an - empty box. */ - int box_width = g->width; - int box_height = gstring->ascent + gstring->descent; - - if (box_width > 4) - box_width -= 2; - if (box_height > 4) - box_height -= 2; - XDrawRectangle (display, (Window) win, gc, - x, y - gstring->ascent, box_width, box_height); - x += g++->width; - } - } - else if (g->xoff != 0 || g->yoff != 0 || g->right_padding) - { - XDrawString16 (display, (Window) win, gc, - x + g->xoff, y + g->yoff, code + (g - from), 1); - x += g->width; - g++; - } - else - { - int orig_x = x; - int code_idx = g - from; - - for (i = 0; - g < to && g->type == GLYPH_CHAR && g->xoff == 0 && g->yoff == 0; - i++, g++) - x += g->width; - XDrawString16 (display, (Window) win, gc, orig_x, y, - code + code_idx, i); - } - } -} - - - -/* XIM (X Input Method) handler */ - -typedef struct MInputXIMMethodInfo -{ - Display *display; - XIM xim; - MSymbol language; - MSymbol coding; -} MInputXIMMethodInfo; - -typedef struct MInputXIMContextInfo -{ - XIC xic; - Window win; - MConverter *converter; -} MInputXIMContextInfo; - -static int -xim_open_im (MInputMethod *im) -{ - MInputXIMArgIM *arg = (MInputXIMArgIM *) im->arg; - MLocale *saved, *this; - char *save_modifier_list; - XIM xim; - MInputXIMMethodInfo *im_info; - - saved = mlocale_set (LC_CTYPE, NULL); - this = mlocale_set (LC_CTYPE, arg->locale ? arg->locale : ""); - if (! this) - /* The specified locale is not supported. */ - MERROR (MERROR_LOCALE, -1); - if (mlocale_get_prop (this, Mcoding) == Mnil) - { - /* Unable to decode the output of XIM. */ - mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname))); - MERROR (MERROR_LOCALE, -1); - } - - if (arg->modifier_list) - save_modifier_list = XSetLocaleModifiers (arg->modifier_list); - else - save_modifier_list = XSetLocaleModifiers (""); - if (! save_modifier_list) - { - /* The specified locale is not supported by X. */ - mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname))); - MERROR (MERROR_LOCALE, -1); - } - - xim = XOpenIM (arg->display, arg->db, arg->res_name, arg->res_class); - if (! xim) - { - /* No input method is available in the current locale. */ - XSetLocaleModifiers (save_modifier_list); - mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname))); - MERROR (MERROR_WIN, -1); - } - - MSTRUCT_MALLOC (im_info, MERROR_WIN); - im_info->display = arg->display; - im_info->xim = xim; - im_info->language = mlocale_get_prop (this, Mlanguage); - im_info->coding = mlocale_get_prop (this, Mcoding); - im->info = im_info; - - XSetLocaleModifiers (save_modifier_list); - mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname))); - - return 0; -} - -static void -xim_close_im (MInputMethod *im) -{ - MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) im->info; - - XCloseIM (im_info->xim); - free (im_info); -} - -int -xim_create_ic (MInputContext *ic) -{ - MInputXIMArgIC *arg = (MInputXIMArgIC *) ic->arg; - MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info; - MInputXIMContextInfo *ic_info; - XIC xic; - - if (! arg->input_style) - { - /* By default, use Root style. */ - arg->input_style = XIMPreeditNothing | XIMStatusNothing; - arg->preedit_attrs = NULL; - arg->status_attrs = NULL; - } - - if (! arg->preedit_attrs && ! arg->status_attrs) - xic = XCreateIC (im_info->xim, - XNInputStyle, arg->input_style, - XNClientWindow, arg->client_win, - XNFocusWindow, arg->focus_win, - NULL); - else if (arg->preedit_attrs && ! arg->status_attrs) - xic = XCreateIC (im_info->xim, - XNInputStyle, arg->input_style, - XNClientWindow, arg->client_win, - XNFocusWindow, arg->focus_win, - XNPreeditAttributes, arg->preedit_attrs, - NULL); - else if (! arg->preedit_attrs && arg->status_attrs) - xic = XCreateIC (im_info->xim, - XNInputStyle, arg->input_style, - XNClientWindow, arg->client_win, - XNFocusWindow, arg->focus_win, - XNStatusAttributes, arg->status_attrs, - NULL); - else - xic = XCreateIC (im_info->xim, - XNInputStyle, arg->input_style, - XNClientWindow, arg->client_win, - XNFocusWindow, arg->focus_win, - XNPreeditAttributes, arg->preedit_attrs, - XNStatusAttributes, arg->status_attrs, - NULL); - if (! xic) - MERROR (MERROR_WIN, -1); - - MSTRUCT_MALLOC (ic_info, MERROR_WIN); - ic_info->xic = xic; - ic_info->win = arg->focus_win; - ic_info->converter = mconv_buffer_converter (im_info->coding, NULL, 0); - ic->info = ic_info; - return 0; -} - -void -xim_destroy_ic (MInputContext *ic) -{ - MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info; - - XDestroyIC (ic_info->xic); - mconv_free_converter (ic_info->converter); - free (ic_info); - ic->info = NULL; -} - -static int -xim_filter (MInputContext *ic, MSymbol key, void *event) -{ - MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info; - - return (XFilterEvent ((XEvent *) event, ic_info->win) == True); -} - - -static int -xim_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt) -{ - MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info; - MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info; - XKeyPressedEvent *ev = (XKeyPressedEvent *) arg; - KeySym keysym; - Status status; - char *buf; - int len; - - buf = (char *) alloca (512); - len = XmbLookupString (ic_info->xic, ev, buf, 512, &keysym, &status); - if (status == XBufferOverflow) - { - buf = (char *) alloca (len); - len = XmbLookupString (ic_info->xic, ev, buf, len, &keysym, &status); - } - - mtext_reset (ic->produced); - if (len == 0) - return 1; - - mconv_reset_converter (ic_info->converter); - mconv_rebind_buffer (ic_info->converter, (unsigned char *) buf, len); - mconv_decode (ic_info->converter, ic->produced); - mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced), - Mlanguage, (void *) im_info->language); - mtext_cpy (mt, ic->produced); - mtext_reset (ic->produced); - return 0; -} - - - -#if 1 -int -x_error_handler (Display *display, XErrorEvent *error) -{ - mdebug_hook (); - return 0; -} - -int -x_io_error_handler (Display *display) -{ - mdebug_hook (); - return 0; -} -#endif - - - -int -mwin__init () -{ - Mdisplay = msymbol ("display"); - Mscreen = msymbol ("screen"); - Mdrawable = msymbol ("drawable"); - Mdepth = msymbol ("depth"); - Mwidget = msymbol ("widget"); - M_iso8859_1 = msymbol ("iso8859-1"); - M_iso10646_1 = msymbol ("iso10646-1"); - - display_info_list = mplist (); - device_list = mplist (); - - mfont__driver_list[MFONT_TYPE_WIN] = &xfont_driver; - - Mxim = msymbol ("xim"); - msymbol_put (Mxim, Minput_driver, &minput_xim_driver); - - return 0; -} - -void -mwin__fini () -{ - M17N_OBJECT_UNREF (display_info_list); - M17N_OBJECT_UNREF (device_list); -} - -typedef struct -{ - String font; - String foreground; - String background; - Boolean reverse_video; -} AppData, *AppDataPtr; - - -int -mwin__parse_font_name (char *name, MFont *font) -{ - char *field[XLFD_FIELD_MAX]; - unsigned short size, resy; - MSymbol attrs[MFONT_PROPERTY_MAX]; - char *copy = (char *) alloca (512); - int i, len; - char *p, *last = NULL; - - len = strlen (name) + 1; - for (i = 0, p = name; *p; p++) - { - if (*p == '-') - i++; - else if (p > name && *p == '*' && p[-1] == '-') - last = p + 1; - } - if (i == 14) - memcpy (copy, name, len); - else if (last) - { - memcpy (copy, name, last - name); - for (; i < 14; i++) - strcat (copy, "-*"); - strcat (copy, last); - } - - if (split_font_name (copy, field, &size, &resy) < 0) - return -1; - attrs[MFONT_FOUNDRY] - = *(field[XLFD_FOUNDRY]) != '*' ? msymbol (field[XLFD_FOUNDRY]) : Mnil; - attrs[MFONT_FAMILY] - = *(field[XLFD_FAMILY]) != '*' ? msymbol (field[XLFD_FAMILY]) : Mnil; - attrs[MFONT_WEIGHT] - = *(field[XLFD_WEIGHT]) != '*' ? msymbol (field[XLFD_WEIGHT]) : Mnil; - attrs[MFONT_STYLE] - = *(field[XLFD_SLANT]) != '*' ? msymbol (field[XLFD_SLANT]) : Mnil; - attrs[MFONT_STRETCH] - = *(field[XLFD_SWIDTH]) != '*' ? msymbol (field[XLFD_SWIDTH]) : Mnil; - attrs[MFONT_ADSTYLE] - = *(field[XLFD_ADSTYLE]) != '*' ? msymbol (field[XLFD_ADSTYLE]) : Mnil; - attrs[MFONT_REGISTRY] - = *(field[XLFD_REGISTRY]) != '*' ? msymbol (field[XLFD_REGISTRY]) : Mnil; - mfont__set_spec (font, attrs, size, resy); - return 0; -} - - -char * -mwin__build_font_name (MFont *font) -{ - char name[1024]; - - if (build_font_name (font, name, 1024) < 0) - return NULL; - return strdup (name); -} - -/** Return an MWDevice object corresponding to a display specified in - PLIST. - - It searches device_list for a device matching the display. If - found, return the found object. Otherwise, return a newly created - object. */ - -MWDevice * -mwin__open_device (MFrame *frame, MPlist *param) -{ - Display *display = NULL; - Screen *screen = NULL; - int screen_num; - Drawable drawable = 0; - Widget widget = NULL; - Colormap cmap = 0; - int auto_display = 0; - MDisplayInfo *disp_info = NULL; - MWDevice *device = NULL; - MSymbol key; - XWindowAttributes attr; - unsigned depth = 0; - MPlist *plist; - - if (param) - for (plist = param; (key = mplist_key (plist)) != Mnil; - plist = mplist_next (plist)) - { - if (key == Mdisplay) - display = (Display *) mplist_value (plist); - else if (key == Mscreen) - screen = mplist_value (plist); - else if (key == Mdrawable) - drawable = (Drawable) mplist_value (plist); - else if (key == Mdepth) - depth = (unsigned) mplist_value (plist); - else if (key == Mwidget) - widget = (Widget) mplist_value (plist); - else if (key == Mcolormap) - cmap = (Colormap) mplist_value (plist); - } - - if (widget) - { - display = XtDisplay (widget); - screen_num = XScreenNumberOfScreen (XtScreen (widget)); - depth = DefaultDepth (display, screen_num); - } - else if (drawable) - { - Window root_window; - int x, y; - unsigned width, height, border_width; - - if (! display) - MERROR (MERROR_WIN, NULL); - XGetGeometry (display, drawable, &root_window, - &x, &y, &width, &height, &border_width, &depth); - XGetWindowAttributes (display, root_window, &attr); - screen_num = XScreenNumberOfScreen (attr.screen); - } - else - { - if (screen) - display = DisplayOfScreen (screen); - else - { - if (! display) - { - display = XOpenDisplay (NULL); - if (! display) - MERROR (MERROR_WIN, NULL); - auto_display = 1; - } - screen = DefaultScreenOfDisplay (display); - } - screen_num = XScreenNumberOfScreen (screen); - if (! depth) - depth = DefaultDepth (display, screen_num); - } - - if (! cmap) - cmap = DefaultColormap (display, screen_num); - - for (plist = display_info_list; mplist_key (plist) != Mnil; - plist = mplist_next (plist)) - { - disp_info = (MDisplayInfo *) mplist_value (plist); - if (disp_info->display == display) - break; - } - - if (mplist_key (plist) != Mnil) - M17N_OBJECT_REF (disp_info); - else - { - M17N_OBJECT (disp_info, free_display_info, MERROR_WIN); - disp_info->display = display; - disp_info->auto_display = auto_display; - disp_info->font_registry_list = mplist (); - disp_info->iso8859_1_family_list = mplist (); - disp_info->iso10646_1_family_list = mplist (); - disp_info->realized_font_list = mplist (); - find_modifier_bits (disp_info); - mplist_add (display_info_list, Mt, disp_info); - } - - for (plist = device_list; mplist_key (plist) != Mnil; - plist = mplist_next (plist)) - { - device = (MWDevice *) mplist_value (plist); - if (device->display_info == disp_info - && device->depth == depth - && device->cmap == cmap) - break; - } - - if (mplist_key (plist) != Mnil) - M17N_OBJECT_REF (device); - else - { - M17N_OBJECT (device, free_device, MERROR_WIN); - device->display_info = disp_info; - device->screen_num = screen_num; - /* A drawable on which to create GCs. */ - device->drawable = XCreatePixmap (display, - RootWindow (display, screen_num), - 1, 1, depth); - device->depth = depth; - device->cmap = cmap; - device->realized_face_list = mplist (); - device->realized_fontset_list = mplist (); - device->foreground = BlackPixel (display, screen_num); - device->background = WhitePixel (display, screen_num); - } - - frame->realized_font_list = disp_info->realized_font_list; - frame->realized_face_list = device->realized_face_list; - frame->realized_fontset_list = device->realized_fontset_list; - - if (widget) - { - AppData app_data; - XtResource resources[] = { - { XtNfont, XtCFont, XtRString, sizeof (String), - XtOffset (AppDataPtr, font), XtRString, - "-misc-fixed-medium-r-normal--*-120-*-*-*-*-iso8859-1" }, - { XtNforeground, XtCForeground, XtRString, sizeof (String), - XtOffset (AppDataPtr, foreground), XtRString, "black" }, - { XtNbackground, XtCBackground, XtRString, sizeof (String), - XtOffset (AppDataPtr, background), XtRString, "white" }, - { XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof (Boolean), - XtOffset (AppDataPtr, reverse_video), XtRImmediate, (caddr_t) FALSE } - }; - MFace *face = NULL; - MFont font; - char **names; - int nfonts; - - XtGetApplicationResources (widget, &app_data, - resources, XtNumber (resources), NULL, 0); - names = XListFonts (display, app_data.font, 1, &nfonts); - if (nfonts == 1) - { - if (mwin__parse_font_name (names[0], &font) >= 0) - face = mface_from_font (&font); - else - { - /* The font name does not conform to XLFD. Try to open the - font and get XA_FONT property. */ - XFontStruct *xfont = XLoadQueryFont (display, names[0]); - - if (xfont) - { - unsigned long value; - char *name; - - if (XGetFontProperty (xfont, XA_FONT, &value) - && (name = ((char *) - XGetAtomName (display, (Atom) value)))) - { - if (mwin__parse_font_name (name, &font) >= 0) - face = mface_from_font (&font); - } - XFreeFont (display, xfont); - } - } - XFreeFontNames (names); - } - - if (app_data.reverse_video == True) - { - if (! face) - face = mface (); - mface_put_prop (face, Mvideomode, Mreverse); - } - if (face) - { - mplist_push (param, Mface, face); - M17N_OBJECT_UNREF (face); - } - device->foreground - = get_color (display, cmap, msymbol (app_data.foreground), Mnil, - device->foreground); - device->background - = get_color (display, cmap, msymbol (app_data.background), Mnil, - device->background); - } - XSetErrorHandler (x_error_handler); - /* XSetIOErrorHandler (x_io_error_handler); */ - - return device; -} - -void -mwin__close_device (MFrame *frame) -{ - M17N_OBJECT_UNREF (frame->device); -} - -void * -mwin__device_get_prop (MWDevice *device, MSymbol key) -{ - if (key == Mdisplay) - return (void *) device->display_info->display; - if (key == Mscreen) - return (void *) ScreenOfDisplay(device->display_info->display, - device->screen_num); - if (key == Mcolormap) - return (void *) device->cmap; - if (key == Mdepth) - return (void *) device->depth; - return NULL; -} - -struct { - int size, inc, used; - GC *gc_table; -} gc_list; - -#define REGISTER_GC(gc) \ - do { \ - if (! gc_list.size) \ - MLIST_INIT1 (&gc_list, gc_table, 100); \ - MLIST_APPEND1 (&gc_list, gc_table, gc, MERROR_WIN); \ - } while (0) - - -#define UNREGISTER_GC(gc) \ - do { \ - int j; \ - for (j = 0; j < gc_list.used; j++) \ - if (gc_list.gc_table[j] == gc) \ - gc_list.gc_table[j] = (GC) NULL; \ - } while (0) - - -void -mwin__realize_face (MRealizedFace *rface) -{ - MFrame *frame = rface->frame; - MWDevice *device = frame->device; - Display *display = FRAME_DISPLAY (frame); - XGCValues values; - int mask = GCForeground | GCBackground; - MSymbol foreground = rface->face.property[MFACE_FOREGROUND]; - MSymbol background = rface->face.property[MFACE_BACKGROUND]; - MFaceHLineProp *hline = rface->hline; - MFaceBoxProp *box = rface->box; - MFaceHookFunc func = (MFaceHookFunc) rface->face.property[MFACE_HOOK_FUNC]; - MSymbol default_foreground - = (MSymbol) mface_get_prop (frame->face, Mforeground); - MSymbol default_background - = (MSymbol) mface_get_prop (frame->face, Mbackground); - GC *gcs; - unsigned long pixel; - - MTABLE_CALLOC (gcs, MFACE_GCS, MERROR_WIN); - - values.foreground = get_color (display, device->cmap, foreground, - default_foreground, device->foreground); - values.background = get_color (display, device->cmap, background, - default_background, device->background); - if (rface->face.property[MFACE_VIDEOMODE] == Mreverse) - pixel = values.foreground, - values.foreground = values.background, - values.background = pixel; - - if (rface->rfont - && rface->rfont->font.property[MFONT_TYPE] - 1 == MFONT_TYPE_WIN) - { - values.font = ((MXFontInfo *) (rface->rfont->info))->f->fid; - mask |= GCFont; - } - - gcs[MFACE_GC_NORMAL] = XCreateGC (display, device->drawable, mask, &values); - REGISTER_GC (gcs[MFACE_GC_NORMAL]); - - gcs[MFACE_GC_SCRATCH] = XCreateGC (display, device->drawable, mask, &values); - REGISTER_GC (gcs[MFACE_GC_SCRATCH]); - - pixel = values.foreground; - values.foreground = values.background; - values.background = pixel; - gcs[MFACE_GC_INVERSE] = XCreateGC (display, device->drawable, mask, &values); - REGISTER_GC (gcs[MFACE_GC_INVERSE]); - values.background = values.foreground; - values.foreground = pixel; - - mask &= ~GCFont; - - if (rface == rface->ascii_rface) - { - /* This realized face is for ASCII. Setup GCs for hline and - box. */ - if (hline && hline->color != foreground) - { - values.foreground - = get_color (display, device->cmap, hline->color, - default_foreground, device->foreground); - gcs[MFACE_GC_HLINE] - = XCreateGC (display, device->drawable, mask, &values); - REGISTER_GC (gcs[MFACE_GC_HLINE]); - values.foreground = pixel; - } - - if (box) - { - if (box->color_top) - { - values.foreground - = get_color (display, device->cmap, box->color_top, - default_foreground, device->foreground); - gcs[MFACE_GC_BOX_TOP] - = XCreateGC (display, device->drawable, mask, &values); - REGISTER_GC (gcs[MFACE_GC_BOX_TOP]); - } - - if (box->color_left - && box->color_left != box->color_top) - { - values.foreground - = get_color (display, device->cmap, box->color_left, - default_foreground, device->foreground); - gcs[MFACE_GC_BOX_LEFT] - = XCreateGC (display, device->drawable, mask, &values); - REGISTER_GC (gcs[MFACE_GC_BOX_LEFT]); - } - - if (box->color_right - && box->color_right != box->color_top) - { - values.foreground - = get_color (display, device->cmap, box->color_right, - default_foreground, device->foreground); - gcs[MFACE_GC_BOX_RIGHT] - = XCreateGC (display, device->drawable, mask, &values); - REGISTER_GC (gcs[MFACE_GC_BOX_RIGHT]); - } - - if (box->color_bottom - && box->color_bottom != box->color_top) - { - values.foreground - = get_color (display, device->cmap, box->color_bottom, - default_foreground, device->foreground); - gcs[MFACE_GC_BOX_BOTTOM] - = XCreateGC (display, device->drawable, mask, &values); - REGISTER_GC (gcs[MFACE_GC_BOX_BOTTOM]); - } - } - } - else - { - /* This realized face is not for ASCII. GCs for hline and box - are shared with that of the corresponding ASCII face. */ - GC *ascii_gcs = rface->ascii_rface->info; - int i; - - for (i = MFACE_GC_HLINE; i < MFACE_GCS; i++) - gcs[i] = ascii_gcs[i]; - } - - rface->info = gcs; - if (func) - (func) (&(rface->face), rface->info, rface->face.property[MFACE_HOOK_ARG]); -} - - -void -mwin__free_realized_face (MRealizedFace *rface) -{ - GC *gcs = rface->info; - enum face_gc limit - = rface == rface->ascii_rface ? MFACE_GCS : MFACE_GC_HLINE; - int i; - - for (i = 0; i < limit; i++) - if (gcs[i]) - { - UNREGISTER_GC (gcs[i]); - XFreeGC (FRAME_DISPLAY (rface->frame), gcs[i]); - } - free (gcs); -} - - -void -mwin__fill_space (MFrame *frame, MDrawWindow win, MRealizedFace *rface, - int reverse, - int x, int y, int width, int height, MDrawRegion region) -{ - GC *gcs = rface->info; - GC gc = gcs[reverse ? MFACE_GC_NORMAL : MFACE_GC_INVERSE]; - - if (region) - gc = set_region (FRAME_DISPLAY (frame), rface, gc, region); - - XFillRectangle (FRAME_DISPLAY (frame), (Window) win, gc, - x, y, width, height); -} - - -void -mwin__draw_hline (MFrame *frame, MDrawWindow win, MGlyphString *gstring, - MRealizedFace *rface, int reverse, - int x, int y, int width, MDrawRegion region) -{ - enum MFaceHLineType type = rface->hline->type; - GC *gcs = rface->info; - GC gc; - int i; - - y = (type == MFACE_HLINE_BOTTOM - ? y + gstring->text_descent - rface->hline->width - : type == MFACE_HLINE_UNDER - ? y + 1 - : type == MFACE_HLINE_STRIKE_THROUGH - ? y - ((gstring->ascent + gstring->descent) / 2) - : y - gstring->text_ascent); - if (reverse) - gc = gcs[MFACE_GC_INVERSE]; - else if (gcs[MFACE_GC_HLINE]) - gc = gcs[MFACE_GC_HLINE]; - else - gc = gcs[MFACE_GC_NORMAL]; - - if (region) - gc = set_region (FRAME_DISPLAY (frame), rface, gc, region); - - for (i = 0; i < rface->hline->width; i++) - XDrawLine (FRAME_DISPLAY (frame), (Window) win, gc, - x, y + i, x + width - 1, y + i); -} - - -void -mwin__draw_box (MFrame *frame, MDrawWindow win, MGlyphString *gstring, - MGlyph *g, int x, int y, int width, MDrawRegion region) -{ - Display *display = FRAME_DISPLAY (frame); - MRealizedFace *rface = g->rface; - MFaceBoxProp *box = rface->box; - GC *gcs = rface->info; - GC gc_top, gc_left, gc_right, gc_btm; - int y0, y1; - int i; - - y0 = y - (gstring->text_ascent - + rface->box->inner_vmargin + rface->box->width); - y1 = y + (gstring->text_descent - + rface->box->inner_vmargin + rface->box->width - 1); - - gc_top = gcs[MFACE_GC_BOX_TOP]; - if (! gc_top) - gc_top = gcs[MFACE_GC_NORMAL]; - if (region) - gc_top = set_region (FRAME_DISPLAY (frame), rface, gc_top, region); - gc_btm = gcs[MFACE_GC_BOX_BOTTOM]; - if (! gc_btm) - gc_btm = gc_top; - - if (g->type == GLYPH_BOX) - { - int x0, x1; - - if (g->left_padding) - x0 = x + box->outer_hmargin, x1 = x + g->width - 1; - else - x0 = x, x1 = x + g->width - box->outer_hmargin - 1; - - /* Draw the top side. */ - for (i = 0; i < box->width; i++) - XDrawLine (display, (Window) win, gc_top, x0, y0 + i, x1, y0 + i); - - /* Draw the bottom side. */ - if (region) - gc_btm = set_region (display, rface, gc_btm, region); - for (i = 0; i < box->width; i++) - XDrawLine (display, (Window) win, gc_btm, x0, y1 - i, x1, y1 - i); - - if (g->left_padding > 0) - { - /* Draw the left side. */ - gc_left = gcs[MFACE_GC_BOX_LEFT]; - if (! gc_left) - gc_left = gc_top; - else if (region) - gc_left = set_region (display, rface, gc_left, region); - for (i = 0; i < rface->box->width; i++) - XDrawLine (display, (Window) win, gc_left, - x0 + i, y0 + i, x0 + i, y1 - i); - } - else - { - /* Draw the right side. */ - gc_right = gcs[MFACE_GC_BOX_RIGHT]; - if (! gc_right) - gc_right = gc_top; - else if (region) - gc_right = set_region (display, rface, gc_right, region); - for (i = 0; i < rface->box->width; i++) - XDrawLine (display, (Window) win, gc_right, - x1 - i, y0 + i, x1 - i, y1 - i); - } - } - else - { - /* Draw the top side. */ - for (i = 0; i < box->width; i++) - XDrawLine (display, (Window) win, gc_top, - x, y0 + i, x + width - 1, y0 + i); - - /* Draw the bottom side. */ - if (region) - gc_btm = set_region (display, rface, gc_btm, region); - for (i = 0; i < box->width; i++) - XDrawLine (display, (Window) win, gc_btm, - x, y1 - i, x + width - 1, y1 - i); - } -} - - -void -mwin__draw_bitmap (MFrame *frame, MDrawWindow win, MRealizedFace *rface, - int reverse, int x, int y, - int width, int height, int row_bytes, unsigned char *bmp, - MDrawRegion region) -{ - Display *display = FRAME_DISPLAY (frame); - int i, j; - GC *gcs = rface->info; - GC gc = gcs[reverse ? MFACE_GC_INVERSE : MFACE_GC_NORMAL]; - - if (region) - gc = set_region (FRAME_DISPLAY (frame), rface, gc, region); - - for (i = 0; i < height; i++, bmp += row_bytes) - for (j = 0; j < width; j++) - if (bmp[j / 8] & (1 << (7 - (j % 8)))) - XDrawPoint (display, (Window) win, gc, x + j, y + i); -} - - -MDrawRegion -mwin__region_from_rect (MDrawMetric *rect) -{ - MDrawRegion region1 = XCreateRegion (); - MDrawRegion region2 = XCreateRegion (); - XRectangle xrect; - - xrect.x = rect->x; - xrect.y = rect->y; - xrect.width = rect->width; - xrect.height = rect->height; - XUnionRectWithRegion (&xrect, region1, region2); - XDestroyRegion (region1); - return region2; -} - -void -mwin__union_rect_with_region (MDrawRegion region, MDrawMetric *rect) -{ - MDrawRegion region1 = XCreateRegion (); - XRectangle xrect; - - xrect.x = rect->x; - xrect.y = rect->y; - xrect.width = rect->width; - xrect.height = rect->height; - - XUnionRegion (region, region, region1); - XUnionRectWithRegion (&xrect, region1, region); - XDestroyRegion (region1); -} - -void -mwin__intersect_region (MDrawRegion region1, MDrawRegion region2) -{ - MDrawRegion region = XCreateRegion (); - - XUnionRegion (region1, region1, region); - XIntersectRegion (region, region2, region1); - XDestroyRegion (region); -} - -void -mwin__region_add_rect (MDrawRegion region, MDrawMetric *rect) -{ - MDrawRegion region1 = XCreateRegion (); - XRectangle xrect; - - xrect.x = rect->x; - xrect.y = rect->y; - xrect.width = rect->width; - xrect.height = rect->height; - XUnionRectWithRegion (&xrect, region1, region); - XDestroyRegion (region1); -} - -void -mwin__region_to_rect (MDrawRegion region, MDrawMetric *rect) -{ - XRectangle xrect; - - XClipBox (region, &xrect); - rect->x = xrect.x; - rect->y = xrect.y; - rect->width = xrect.width; - rect->height = xrect.height; -} - -void -mwin__free_region (MDrawRegion region) -{ - XDestroyRegion (region); -} - -void -mwin__dump_region (MDrawRegion region) -{ - XRectangle rect; - XClipBox (region, &rect); - fprintf (stderr, "(%d %d %d %d)\n", rect.x, rect.y, rect.width, rect.height); -} - -void -mwin__verify_region (MFrame *frame, MDrawRegion region) -{ - set_region (FRAME_DISPLAY (frame), frame->rface, - ((GC *) frame->rface->info)[MFACE_GC_NORMAL], region); -} - -MDrawWindow -mwin__create_window (MFrame *frame, MDrawWindow parent) -{ - MWDevice *device = frame->device; - Display *display = FRAME_DISPLAY (frame); - int screen = FRAME_SCREEN (frame); - Window win; - XWMHints wm_hints = { InputHint, False }; - XClassHint class_hints = { "M17N-IM", "m17n-im" }; - XSetWindowAttributes attrs; - unsigned long mask; - MSymbol background = mface_get_prop (frame->face, Mbackground); - - attrs.background_pixel = get_color (display, device->cmap, - background, background, - WhitePixel (display, screen)); - attrs.backing_store = Always; - attrs.override_redirect = True; - attrs.save_under = True; - mask = CWBackPixel | CWBackingStore | CWOverrideRedirect | CWSaveUnder; - if (! parent) - parent = (MDrawWindow) RootWindow (display, screen); - win = XCreateWindow (display, (Window) parent, 0, 0, 1, 1, 0, - CopyFromParent, InputOutput, CopyFromParent, - mask, &attrs); - XSetWMProperties (display, (Window) win, NULL, NULL, NULL, 0, - NULL, &wm_hints, &class_hints); - XSelectInput (display, (Window) win, StructureNotifyMask | ExposureMask); - return (MDrawWindow) win; -} - -void -mwin__destroy_window (MFrame *frame, MDrawWindow win) -{ - XDestroyWindow (FRAME_DISPLAY (frame), (Window) win); -} - -#if 0 -MDrawWindow -mwin__event_window (void *event) -{ - return ((MDrawWindow) ((XEvent *) event)->xany.window); -} - -void -mwin__print_event (void *arg, char *win_name) -{ - char *event_name; - XEvent *event = (XEvent *) arg; - - switch (event->xany.type) - { - case 2: event_name = "KeyPress"; break; - case 3: event_name = "KeyRelease"; break; - case 4: event_name = "ButtonPress"; break; - case 5: event_name = "ButtonRelease"; break; - case 6: event_name = "MotionNotify"; break; - case 7: event_name = "EnterNotify"; break; - case 8: event_name = "LeaveNotify"; break; - case 9: event_name = "FocusIn"; break; - case 10: event_name = "FocusOut"; break; - case 11: event_name = "KeymapNotify"; break; - case 12: event_name = "Expose"; break; - case 13: event_name = "GraphicsExpose"; break; - case 14: event_name = "NoExpose"; break; - case 15: event_name = "VisibilityNotify"; break; - case 16: event_name = "CreateNotify"; break; - case 17: event_name = "DestroyNotify"; break; - case 18: event_name = "UnmapNotify"; break; - case 19: event_name = "MapNotify"; break; - case 20: event_name = "MapRequest"; break; - case 21: event_name = "ReparentNotify"; break; - case 22: event_name = "ConfigureNotify"; break; - case 23: event_name = "ConfigureRequest"; break; - case 24: event_name = "GravityNotify"; break; - case 25: event_name = "ResizeRequest"; break; - case 26: event_name = "CirculateNotify"; break; - case 27: event_name = "CirculateRequest"; break; - case 28: event_name = "PropertyNotify"; break; - case 29: event_name = "SelectionClear"; break; - case 30: event_name = "SelectionRequest"; break; - case 31: event_name = "SelectionNotify"; break; - case 32: event_name = "ColormapNotify"; break; - case 33: event_name = "ClientMessage"; break; - case 34: event_name = "MappingNotify"; break; - default: event_name = "unknown"; - } - - fprintf (stderr, "%s: %s\n", win_name, event_name); -} -#endif - -void -mwin__map_window (MFrame *frame, MDrawWindow win) -{ - XMapRaised (FRAME_DISPLAY (frame), (Window) win); -} - -void -mwin__unmap_window (MFrame *frame, MDrawWindow win) -{ - XUnmapWindow (FRAME_DISPLAY (frame), (Window) win); -} - -void -mwin__window_geometry (MFrame *frame, MDrawWindow win, MDrawWindow parent_win, - MDrawMetric *geometry) -{ - Display *display = FRAME_DISPLAY (frame); - XWindowAttributes attr; - Window parent = (Window) parent_win, root; - - XGetWindowAttributes (display, (Window) win, &attr); - geometry->x = attr.x + attr.border_width; - geometry->y = attr.y + attr.border_width; - geometry->width = attr.width; - geometry->height = attr.height; - - if (! parent) - parent = RootWindow (display, FRAME_SCREEN (frame)); - while (1) - { - Window this_parent, *children; - unsigned n; - - XQueryTree (display, (Window) win, &root, &this_parent, &children, &n); - if (children) - XFree (children); - if (this_parent == parent || this_parent == root) - break; - win = (MDrawWindow) this_parent; - XGetWindowAttributes (display, (Window) win, &attr); - geometry->x += attr.x + attr.border_width; - geometry->y += attr.y + attr.border_width; - } -} - -void -mwin__adjust_window (MFrame *frame, MDrawWindow win, - MDrawMetric *current, MDrawMetric *new) -{ - Display *display = FRAME_DISPLAY (frame); - unsigned int mask = 0; - XWindowChanges values; - - if (current->width != new->width) - { - mask |= CWWidth; - if (new->width <= 0) - new->width = 1; - values.width = current->width = new->width; - } - if (current->height != new->height) - { - mask |= CWHeight; - if (new->height <= 0) - new->height = 1; - values.height = current->height = new->height; - } - if (current->x != new->x) - { - mask |= CWX; - values.x = current->x = new->x; - } - if (current->y != new->y) - { - mask |= CWY; - current->y = new->y; - values.y = current->y = new->y; - } - if (mask) - XConfigureWindow (display, (Window) win, mask, &values); -} - -MSymbol -mwin__parse_event (MFrame *frame, void *arg, int *modifiers) -{ - XEvent *event = (XEvent *) arg; - MDisplayInfo *disp_info = frame->device->display_info; - int len; - char buf[512]; - KeySym keysym; - MSymbol key; - - *modifiers = 0; - if (event->xany.type != KeyPress - /* && event->xany.type != KeyRelease */ - ) - return Mnil; - len = XLookupString ((XKeyEvent *) event, (char *) buf, 512, &keysym, NULL); - if (len > 1) - return Mnil; - if (len == 1) - { - int c = buf[0]; - - if ((c == ' ' || c == 127) && ((XKeyEvent *) event)->state & ShiftMask) - *modifiers |= MINPUT_KEY_SHIFT_MODIFIER; - if (((XKeyEvent *) event)->state & ControlMask) - { - c &= 0x1F; - if (((XKeyEvent *) event)->state & ShiftMask) - *modifiers |= MINPUT_KEY_SHIFT_MODIFIER; - } - if (((XKeyEvent *) event)->state & disp_info->meta_mask) - c |= 0x80; - key = minput__char_to_key (c); - } - else if (keysym >= XK_Shift_L && keysym <= XK_Hyper_R) - return Mnil; - else - { - char *str = XKeysymToString (keysym); - - if (! str) - return Mnil; - key = msymbol (str); - if (((XKeyEvent *) event)->state & ShiftMask) - *modifiers |= MINPUT_KEY_SHIFT_MODIFIER; - if (((XKeyEvent *) event)->state & ControlMask) - *modifiers |= MINPUT_KEY_CONTROL_MODIFIER; - } - if (((XKeyEvent *) event)->state & disp_info->meta_mask) - *modifiers |= MINPUT_KEY_META_MODIFIER; - if (((XKeyEvent *) event)->state & disp_info->alt_mask) - *modifiers |= MINPUT_KEY_ALT_MODIFIER; - if (((XKeyEvent *) event)->state & disp_info->super_mask) - *modifiers |= MINPUT_KEY_SUPER_MODIFIER; - if (((XKeyEvent *) event)->state & disp_info->hyper_mask) - *modifiers |= MINPUT_KEY_HYPER_MODIFIER; - - return key; -} - - -MText * -mwin__get_selection_text (MFrame *frame) -{ - return NULL; -} - - -void -mwin__dump_gc (MFrame *frame, MRealizedFace *rface) -{ - unsigned long valuemask = GCForeground | GCBackground | GCClipMask; - XGCValues values; - Display *display = FRAME_DISPLAY (frame); - GC *gcs = rface->info; - int i; - - for (i = 0; i <= MFACE_GC_SCRATCH; i++) - { - XGetGCValues (display, gcs[i], valuemask, &values); - fprintf (stderr, "GC%d: fore/#%lX back/#%lX", i, - values.foreground, values.background); - fprintf (stderr, "\n"); - } -} - -/*** @} */ -#endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */ - -/* External API */ - -/*=*/ -/*** @addtogroup m17nFrame */ -/*** @{ */ -/*=*/ - -/***en - @name Variables: Keys of frame parameter (X specific). - - These are the symbols to use as parameter keys for the function - mframe () (which see). They are also keys of a frame property - (except for #Mwidget). */ -/*=*/ -/*** @{ */ -/* Keywords for mwin__open_device (). */ -MSymbol Mdisplay, Mscreen, Mdrawable, Mdepth, Mwidget, Mcolormap; - -/*** @} */ -/*** @} */ - -/*=*/ -/*** @addtogroup m17nInputMethodWin */ -/*=*/ -/*** @{ */ - -/***en - @brief Input driver for XIM. - - The input driver #minput_xim_driver is for the foreign input - method of name #Mxim. It uses XIM (X Input Methods) as a - background input engine. - - As the symbol #Mxim has property #Minput_driver whose value is - a pointer to this driver, the input method of language #Mnil - and name #Mxim uses this driver. - - Therefore, for such input methods, the driver dependent arguments - to the functions whose name begin with minput_ must be as follows. - - The argument $ARG of the function minput_open_im () must be a - pointer to the structure #MInputXIMArgIM. See the documentation - of #MInputXIMArgIM for more detail. - - The argument $ARG of the function minput_create_ic () must be a - pointer to the structure #MInputXIMArgIC. See the documentation - of #MInputXIMArgIC for more detail. - - The argument $ARG of the function minput_filter () must be a - pointer to the structure @c XEvent. The argument $KEY is ignored. - - The argument $ARG of the function minput_lookup () must be the - same one as that of the function minput_filter (). The argument - $KEY is ignored. */ - -/***ja - @brief XIMÍÑÆþÎϥɥ饤¥Ð - - ÆþÎϥɥ饤¥Ð #minput_xim_driver ¤Ï #Mxim ¤ò̾Á°¤È¤·¤Æ»ý¤Ä³°Éô - ÆþÎϥ᥽¥Ã¥ÉÍѤǤ¢¤ê¡¢ XIM (X Input Methods) ¤ò¥Ð¥Ã¥¯¥°¥é¥¦¥ó¥É¤Î - ÆþÎÏ¥¨¥ó¥¸¥ó¤È¤·¤Æ»ÈÍѤ¹¤ë¡£ - - ¥·¥ó¥Ü¥ë #Mxim ¤Ï¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÃͤȤ¹¤ë¥×¥í¥Ñ¥Æ¥£ - #Minput_driver ¤ò»ý¤Ä¤¿¤á¡¢LANGUAGE ¤¬ #Mnil ¤Ç̾Á°¤¬ #Mxim ¤Ç - ¤¢¤ëÆþÎϥ᥽¥Ã¥É¤Ï¤³¤Î¥É¥é¥¤¥Ð¤òÍøÍѤ¹¤ë¡£ - - ¤·¤¿¤¬¤Ã¤Æ¡¢¤½¤ì¤é¤ÎÆþÎϥ᥽¥Ã¥ÉÍѤˤϡ¢minput_ ¤Ç»Ï¤Þ¤ë̾Á°¤ò»ý¤Ä - °Ê²¼¤Î´Ø¿ô·²¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô¤Ï¼¡¤Î¤è¤¦¤Ê¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é - ¤Ê¤¤¡£ - - ´Ø¿ô minput_open_im () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIM ¤Ø¤Î - ¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIM ¤Î¥É - ¥­¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£ - - ´Ø¿ô minput_create_ic () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIC ¤Ø - ¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIC ¤Î - ¥É¥­¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£ - - ´Ø¿ô minput_filter () ¤Î°ú¿ô %ARG ¤Ï¹½Â¤ÂÎ @c XEvent ¤Ø¤Î¥Ý¥¤¥ó¥¿ - ¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£°ú¿ô $KEY ¤Ï̵»ë¤µ¤ì¤ë¡£ - - ´Ø¿ô minput_lookup () ¤Î°ú¿ô $ARG ¤Ï´Ø¿ô function minput_filter () - ¤Î°ú¿ô $ARG ¤ÈƱ¤¸¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ °ú¿ô $KEY ¤Ï¡¢Ìµ»ë¤µ¤ì - ¤ë¡£ */ - -MInputDriver minput_xim_driver = - { xim_open_im, xim_close_im, xim_create_ic, xim_destroy_ic, - xim_filter, xim_lookup, NULL }; - -/*=*/ - -/***en - @brief Symbol of the name "xim". - - The variable Mxim is a symbol of name "xim". It is a name of the - input method driver #minput_xim_driver. */ - -MSymbol Mxim; - -/*** @} */ - -/* - Local Variables: - coding: euc-japan - End: -*/ diff --git a/src/m17n-X.h b/src/m17n-X.h deleted file mode 100644 index 8f3c670..0000000 --- a/src/m17n-X.h +++ /dev/null @@ -1,161 +0,0 @@ -/* m17n-X.h -- header file for the GUI API on X Windows. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -#ifndef _M17N_X_H_ -#define _M17N_X_H_ - -#include -#include -#include - -#ifdef __cplusplus -extern "C" -{ -#endif - -/* For drawing. */ - -extern MSymbol Mdisplay; -extern MSymbol Mscreen; -extern MSymbol Mdrawable; -extern MSymbol Mwidget; -extern MSymbol Mdepth; -extern MSymbol Mcolormap; - -/* For inputting. */ - -extern MInputDriver minput_xim_driver; -extern MSymbol Mxim; - -/*** @ingroup m17nInputMethodWin */ -/***en - @brief Structure pointed to by the argument $ARG of the function - input_open_im (). - - The type #MInputXIMArgIM is the structure pointed to by the - argument $ARG of the function minput_open_im () for the foreign - input method of name #Mxim. */ - -/***ja - @brief ´Ø¿ô minput_open_im () ¤Î°ú¿ô $ARG ¤Ë¤è¤Ã¤Æ»Ø¤µ¤ì¤ë¹½Â¤ÂÎ - - - #MInputXIMArgIM ·¿¤Ï¡¢´Ø¿ô minput_open_im () ¤¬Ì¾Á° #Mxim ¤ò»ý - ¤Ä³°ÉôÆþÎϥ᥽¥Ã¥É¤òÀ¸À®¤¹¤ëºÝ¤Ë°ú¿ô $ARG ¤Ë¤è¤Ã¤Æ»Ø¤µ¤ì¤ë¹½Â¤ÂÎ¤Ç - ¤¢¤ë¡£ */ - -typedef struct -{ - /***en The meaning of the following four members are the same as - arguments to XOpenIM (). */ - /***ja °Ê²¼¤Î£´¤Ä¤Î¥á¥ó¥Ð¤Î°ÕÌ£¤Ï¡¢XOpenIM () ¤Î°ú¿ô¤Î°ÕÌ£¤ÈƱ¤¸¤Ç¤¢ - ¤ë¡£ */ - - /***en Display of the client. */ - /***ja ¥¯¥é¥¤¥¢¥ó¥È¤Î¥Ç¥£¥¹¥×¥ì¥¤ */ - Display *display; - - /***en Pointer to the X resource database. */ - /***ja X ¥ê¥½¡¼¥¹¡¦¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ø¤Î¥Ý¥¤¥ó¥¿ */ - XrmDatabase db; - - /***en Full class name of the application. */ - /***ja ¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Î´°Á´¤Ê¥¯¥é¥¹Ì¾ */ - char *res_class; - - /***en Full resource name of the application. */ - /***ja ¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Î´°Á´¤Ê¥ê¥½¡¼¥¹Ì¾ */ - char *res_name; - - /***en Locale name under which an XIM is opened. */ - /***ja XIM¤¬¥ª¡¼¥×¥ó¤µ¤ì¤¿¥í¥±¡¼¥ë̾ */ - char *locale; - - /***en Arguments to XSetLocaleModifiers (). */ - /***ja XSetLocaleModifiers () ¤Î°ú¿ô */ - char *modifier_list; -} MInputXIMArgIM; - /*=*/ - -/*** @ingroup m17nInputMethodWin */ -/***en - @brief Structure pointed to by the argument $ARG of the function - minput_create_ic. - - The type #MInputXIMArgIC is the structure pointed to by the - argument $ARG of the function minput_create_ic () for the foreign - input method of name #Mxim. */ - -/***ja - @brief ´Ø¿ô minput_create_ic () ¤Î°ú¿ô $ARG ¤Ë¤è¤Ã¤Æ»Ø¤µ¤ì¤ë¹½Â¤ÂÎ - - #MInputXIMArgIC ·¿¤Ï¡¢´Ø¿ô minput_create_ic () ¤¬Ì¾Á° #Mxim ¤ò - »ý¤Ä³°ÉôÆþÎϥ᥽¥Ã¥ÉÍѤ˸ƤФì¤ëºÝ¤Ë¡¢°ú¿ô $ARG ¤Ë¤è¤Ã¤Æ»Ø¤µ¤ì¤ë¹½ - ¤ÂΤǤ¢¤ë¡£ */ - -typedef struct -{ - /***en Used as the arguments of @c XCreateIC following @c - XNInputStyle. If this is zero, ( @c XIMPreeditNothing | @c - XIMStatusNothing) is used, and and - are set to @c NULL. */ - /***ja @c XCreateIC ¤Î @c XNInputStyle ¤Ë³¤¯°ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£ - ¥¼¥í¤Ê¤é¤Ð¡¢ ( @c XIMPreeditNothing | @c XIMStatusNothing) ¤¬ÍÑ - ¤¤¤é¤ì¡¢ ¤È ¤Ï @c NULL ¤ËÀßÄꤵ¤ì - ¤ë¡£ */ - - XIMStyle input_style; - /***en Used as the argument of @c XCreateIC following @c XNClientWindow. */ - /***ja @c XCreateIC ¤Î @c XNClientWindow ¤Ë³¤¯°ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£ */ - - - Window client_win; - /***en Used as the argument of @c XCreateIC following @c XNFocusWindow. */ - /***ja @c XCreateIC ¤Î @c XNFocusWindow ¤Ë³¤¯°ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£ */ - - Window focus_win; - /***en If non- @c NULL, used as the argument of @c XCreateIC following - @c XNPreeditAttributes. */ - /***ja @c NULL¤Ç¤Ê¤±¤ì¤Ð¡¢ @c XCreateIC following ¤Î@c - XNPreeditAttributes ¤Ë³¤¯°ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£ */ - - XVaNestedList preedit_attrs; - /***en If non-NULL, used as the argument of @c XCreateIC following - @c XNStatusAttributes. */ - /***ja @c NULL¤Ç¤Ê¤±¤ì¤Ð¡¢ @c XCreateIC following ¤Î @c - XNStatusAttributes ¤Ë³¤¯°ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£ */ - - XVaNestedList status_attrs; -} MInputXIMArgIC; -/*=*/ - -#ifdef __cplusplus -} -#endif - -#endif /* not _M17N_X_H_ */ - -/* - Local Variables: - coding: euc-japan - End: -*/ diff --git a/src/m17n-core.c b/src/m17n-core.c deleted file mode 100644 index eeee07f..0000000 --- a/src/m17n-core.c +++ /dev/null @@ -1,758 +0,0 @@ -/* m17n-core.c -- body of the CORE API. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -/***en - @addtogroup m17nIntro - @brief Introduction to the m17n library - - API LEVELS - - The API of the m17n library is divided into these four. - -
    -
  1. CORE API - - It provides basic modules to handle M-texts. They don't require - the m17n database. To use this API, an application program must - include and be linked by -lm17n-core. - -
  2. SHELL API - - It provides modules that utilize the m17n database. They load - various kinds of data from the database on demand. To use this - API, an application program must include and be linked by - -lm17n-core -lm17n. With that, CORE API is also available. - -
  3. GUI API - - It provides GUI modules such as drawing and inputting M-texts on a - window system. The API itself is independent on a window system, - but the m17n library must be configured to use a specific window - system. Currently, we support only the X Window System. To use - this API, an application program must include and - , and be linked by -lm17n-core -lm17n -lm17n-X. With - that, CORE and SHELL APIs are also available. - -
  4. MISC API - - It provides miscellaneous functions to support error handling and - debugging. This API can't be used by itself, but with one or more - APIs listed above. To use the API, an application program must - include in addition to one of , - , and . - -
- - See also the section @ref m17n-config "m17n-config(1)". - - ENVIRONMENT VARIABLE - - The m17n library pays attention to these environment variables. - -
    -
  • @c M17NDIR - - Name of a directory that contains data of the m17n database. See - @ref m17nDatabase for the detail. - -
  • @c MDEBUG_XXXX - - Environment variables whose name start by "MDEBUG_" controls - printing of debug information. See @ref m17nDebug for the detail. - -
- - API NAMING CONVENTION - - The library exports functions, variables, macros, and types. All - of them start by the letter 'm' or 'M' followed by an object name - (e.g. "symbol" and "plist", but "mtext" object is given the name - "text" to avoid double 'm' at the head) or a module name - (e.g. draw, input). - -
    - -
  • functions -- mobject () or mobject_xxx () - - They start with 'm' followed by lower case object name. For - example, msymbol (), mtext_ref_char (), mdraw_text (). - -
  • non-symbol variables -- mobject, or mobject_xxx - - The naming convention is the same as functions (e.g. mface_large). - -
  • symbol variables -- Mname - - Variables of type MSymbol start with 'M' followed by their names - (e.g. Mlanguage (name is "langauge"), Miso_2022 (name is - "iso-2022"). - -
  • macross -- MOBJECT_XXX - - They start by 'M' followed by upper case object names. - -
  • types -- MObject or MObjectXxx - - They start by 'M' followed by capitalized object names (e.g. - MConverter, MInputDriver). - -
- - */ - -/***ja - @addtogroup m17nIntro - - @e m17n¥é¥¤¥Ö¥é¥ê ¤Ï C ¸À¸ìÍÑ¿¸À¸ì¾ðÊó½èÍý¥é¥¤¥Ö¥é¥ê¤Ç¤¢¤ë¡£ - ¤³¤Î¥é¥¤¥Ö¥é¥ê¤Ï¡¢Â¿¸À¸ìʸ½ñ¤ò°·¤¦¤¿¤á¤ËɬÍפʰʲ¼¤Î´ðËܵ¡Ç½¤ò¥¢¥× - ¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤ËÄ󶡤¹¤ë¡£ - - @li ¿¸À¸ì¥Æ¥­¥¹¥ÈÍÑ¥ª¥Ö¥¸¥§¥¯¥È¤È¤·¤Æ¤Î¹½Â¤ÂÎ @e M-text - - @li M-text ¤ò°·¤¦¤¿¤á¤Î¿¤¯¤Î´Ø¿ô¡¦¥Þ¥¯¥í·² - - @li ¼ï¡¹¤Î¥Õ¥©¡¼¥Þ¥Ã¥È¤Ç¥¨¥ó¥³¡¼¥É¤µ¤ì¤¿¥Æ¥­¥¹¥È¤È M-text ´Ö¤ÎÊÑ´¹ - ¤ò¹Ô¤Ê¤¦¥Ç¥³¡¼¥À¡¿¥¨¥ó¥³¡¼¥À - - @li Unicode ¤ÎÁ´¤Æ¤Îʸ»ú¤Ë²Ã¤¨¡¢¤½¤ì¤ÈƱ¤¸¿ô¤ÎÈó Unicode ʸ»ú¤ò°· - ¤¨¤ëµðÂç¤Êʸ»ú¶õ´Ö - - @li ʸ»úËè¤Î¾ðÊó¤ò¸úΨÎɤ¯³ÊǼ¤¹¤ë¹½Â¤ÂÎ @e ʸ»ú¥Æ¡¼¥Ö¥ë (CharTable) - - @li ¥ª¥×¥·¥ç¥ó¡§M-text¤Î¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥à¾å¤Ç¤Îɽ¼¨¡¦ÆþÎÏ¥·¥¹¥Æ¥à¡£ - ¡Ê¤³¤Î¤¿¤á¤Î API ¤Ï m17n-win.h ¤Ë´Þ¤Þ¤ì¤Æ¤¤¤ë¡£¡Ë */ -/*=*/ -/*** @{ */ -#ifdef FOR_DOXYGEN -/***en - The #M17NLIB_MAJOR_VERSION macro gives the major version number - of the m17n library. */ - -/***ja - ¥Þ¥¯¥í #M17NLIB_MAJOR_VERSION ¤Ï m17n ¥é¥¤¥Ö¥é¥ê¤Î¥á¥¸¥ã¡¼¥Ð¡¼¥¸¥ç - ¥óÈÖ¹æ¤òÍ¿¤¨¤ë¡£ */ - -#define M17NLIB_MAJOR_VERSION - -/*=*/ - -/***en - The #M17NLIB_MINOR_VERSION macro gives the minor version number - of the m17n library. */ - -/***ja - ¥Þ¥¯¥í #M17NLIB_MINOR_VERSION ¤Ï m17n ¥é¥¤¥Ö¥é¥ê¤Î¥Þ¥¤¥Ê¡¼¥Ð¡¼¥¸¥ç - ¥óÈÖ¹æ¤òÍ¿¤¨¤ë¡£ */ - -#define M17NLIB_MINOR_VERSION - -/*=*/ - -/***en - The #M17NLIB_VERSION_NAME macro gives the version name of the - m17n library as a string. */ - -/***ja - ¥Þ¥¯¥í #M17NLIB_VERSION_NAME ¤Ï m17n ¥é¥¤¥Ö¥é¥ê¤Î¥Ð¡¼¥¸¥ç¥ó̾¤ò - C-string ¤Î·Á¤ÇÍ¿¤¨¤ë¡£ */ - -#define M17NLIB_VERSION_NAME - -/*=*/ - -/***en - @brief Initialize the m17n library. - - The macro M17N_INIT () initializes the m17n library. This - function must be called before any m17n functions are used. - - If the initialization was successful, the external variable @c - merror_code is set to 0. Otherwise it is set to -1. */ - -/***ja - @brief m17n ¥é¥¤¥Ö¥é¥ê¤Î½é´ü²½ - - ¥Þ¥¯¥í M17N_INIT () ¤Ï m17n ¥é¥¤¥Ö¥é¥ê¤ò½é´ü²½¤¹¤ë¡£m17n ¥é¥¤¥Ö¥é - ¥ê¤ò»È¤¦¤È¤­¤Ï¡¢ºÇ½é¤Ë¤³¤Î´Ø¿ô¤ò¸Æ¤Ð¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ - - ÊÑ¿ô #merror_code ¤Ï¡¢½é´ü²½¤¬À®¸ù¤¹¤ì¤Ð 0 ¤Ë¡¢¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 - ¤ËÀßÄꤵ¤ì¤ë¡£ */ - -#define M17N_INIT() - -/*=*/ - -/***en - @brief Finalize the m17n library. - - The macro M17N_FINI () finalizes the m17n library. It frees all the - memory area used by the m17n library. Once this function is - called, no m17n functions should be used until the - macro M17N_INIT () is called again. */ - -/***ja - @brief m17n ¥é¥¤¥Ö¥é¥ê¤Î½ªÎ» */ - -#define M17N_FINI() -#endif /* FOR_DOXYGEN */ -/*=*/ -/*** @} */ -/*=*/ - -#if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE) -/*** @addtogroup m17nInternal - @{ */ - -#include -#include -#include -#include -#include -#include - -#include "m17n-core.h" -#include "m17n-misc.h" -#include "internal.h" - -static int core_initialized; - -static void -default_error_handler (enum MErrorCode err) -{ - exit (err); -} - -static struct timeval time_stack[16]; -static int time_stack_index; - -static int report_header_printed; - - -/* Internal API */ - -void -mdebug__report_object (char *name, M17NObjectArray *array) -{ - if (! (mdebug__flag & MDEBUG_FINI)) - return; - if (! report_header_printed) - { - fprintf (stderr, "%16s %7s %7s %7s\n", - "object", "created", "freed", "alive"); - fprintf (stderr, "%16s %7s %7s %7s\n", - "------", "-------", "-----", "-----"); - report_header_printed = 1; - } - fprintf (stderr, "%16s %7d %7d %7d\n", name, - array->used, array->used - array->count, array->count); -} - - -void *(*mdatabase__finder) (MSymbol tag1, MSymbol tag2, - MSymbol tag3, MSymbol tag4); -void *(*mdatabase__loader) (void *); - -int mdebug__flag; - -void -mdebug__push_time () -{ - struct timezone tz; - - gettimeofday (time_stack + time_stack_index++, &tz); -} - -void -mdebug__pop_time () -{ - time_stack_index--; -} - -void -mdebug__print_time () -{ - struct timeval tv; - struct timezone tz; - long diff; - - gettimeofday (&tv, &tz); - diff = ((tv.tv_sec - time_stack[time_stack_index - 1].tv_sec) * 1000000 - + (tv.tv_usec - time_stack[time_stack_index - 1].tv_usec)); - fprintf (stderr, "%8ld ms.", diff); - time_stack[time_stack_index - 1] = tv; -} - -#define SET_DEBUG_FLAG(env_name, mask) \ - do { \ - char *env_value = getenv (env_name); \ - \ - if (env_value && env_value[0] == '1') \ - mdebug__flag |= (mask); \ - } while (0) - - - -/* External API */ - -/* The following two are actually not exposed to a user but concealed - by the macro M17N_INIT (). */ - -void -m17n_init_core (void) -{ - int mdebug_mask = MDEBUG_INIT; - - if (core_initialized) - return; - - merror_code = 0; - m17n_memory_full_handler = default_error_handler; - - mdebug__flag = 0; - SET_DEBUG_FLAG ("MDEBUG_INIT", MDEBUG_INIT); - SET_DEBUG_FLAG ("MDEBUG_FINI", MDEBUG_FINI); - SET_DEBUG_FLAG ("MDEBUG_CHARSET", MDEBUG_CHARSET); - SET_DEBUG_FLAG ("MDEBUG_CODING", MDEBUG_CODING); - SET_DEBUG_FLAG ("MDEBUG_DATABASE", MDEBUG_DATABASE); - SET_DEBUG_FLAG ("MDEBUG_FONT", MDEBUG_FONT); - SET_DEBUG_FLAG ("MDEBUG_FONT_FLT", MDEBUG_FONT_FLT); - SET_DEBUG_FLAG ("MDEBUG_FONT_OTF", MDEBUG_FONT_OTF); - SET_DEBUG_FLAG ("MDEBUG_INPUT", MDEBUG_INPUT); - - MDEBUG_PUSH_TIME (); - MDEBUG_PUSH_TIME (); - if (msymbol__init () < 0) - goto err; - MDEBUG_PRINT_TIME ("INIT", (stderr, " to initialize symbol module.")); - if (mplist__init () < 0) - goto err; - MDEBUG_PRINT_TIME ("INIT", (stderr, " to initialize plist module.")); - if (mtext__init () < 0) - goto err; - if (mtext__prop_init () < 0) - goto err; - MDEBUG_PRINT_TIME ("INIT", (stderr, " to initialize mtext module.")); - if (mchartable__init () < 0) - goto err; - MDEBUG_PRINT_TIME ("INIT", (stderr, " to initialize chartable module.")); - - mdatabase__finder = NULL; - mdatabase__loader = NULL; - core_initialized = 1; - - err: - MDEBUG_POP_TIME (); - MDEBUG_PRINT_TIME ("INIT", (stderr, " to initialize the core modules.")); - MDEBUG_POP_TIME (); - - report_header_printed = 0; -} - -void -m17n_fini_core (void) -{ - int mdebug_mask = MDEBUG_FINI; - - if (core_initialized) - { - MDEBUG_PUSH_TIME (); - MDEBUG_PUSH_TIME (); - MDEBUG_PRINT_TIME ("INIT", (stderr, " to finalize chartable module.")); - mchartable__fini (); - MDEBUG_PRINT_TIME ("INIT", (stderr, " to finalize textprop module.")); - mtext__prop_fini (); - MDEBUG_PRINT_TIME ("INIT", (stderr, " to finalize mtext module.")); - mtext__fini (); - MDEBUG_PRINT_TIME ("INIT", (stderr, " to finalize symbol module.")); - msymbol__fini (); - MDEBUG_PRINT_TIME ("INIT", (stderr, " to finalize plist module.")); - mplist__fini (); - core_initialized = 0; - MDEBUG_POP_TIME (); - MDEBUG_PRINT_TIME ("INIT", (stderr, " to finalize the core modules.")); - MDEBUG_POP_TIME (); - } -} - -/*** @} */ -#endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */ -/*=*/ - -/***en - @addtogroup m17nObject - @brief Managed objects are objects managed by the reference count. - - There are some types of m17n objects that are managed by their - reference count. Those objects are called @e managed @e objects. - When created, the reference count of a managed object is - initialized to one. The m17n_object_ref () function increments - the reference count of a managed object by one, and the - m17n_object_unref () function decrements by one. A managed - object is automatically freed when its reference count becomes - zero. - - A property whose key is a managing key can have only a managed - object as its value. Such functions as msymbol_put () and - mplist_put () pay special attention to such a property. - - In addition to the predefined managed object types, users can - define their own managed object types. See the documentation of - the m17n_object () for the details. */ - -/*** @{ */ -/*=*/ -/***en - @brief Allocate a managed object. - - The m17n_object () function allocates a new managed object of - $SIZE bytes and sets its reference count to 1. $FREER is the - function that is used to free the object when the reference count - becomes 0. If $FREER is NULL, the object is freed by the free () - function. - - The heading bytes of the allocated object is occupied by - #M17NObjectHead. That area is reserved for the m17n library and - application programs should never touch it. - - @return - This function returns a newly allocated object. - - @errors - This function never fails. */ - -#if EXAMPLE_CODE -typedef struct -{ - M17NObjectHead head; - int mem1; - char *mem2; -} MYStruct; - -void -my_freer (void *obj) -{ - free (((MYStruct *) obj)->mem2); - free (obj); -} - -void -my_func (MText *mt, MSymbol key, int num, char *str) -{ - MYStruct *st = m17n_object (sizeof (MYStruct), my_freer); - - st->mem1 = num; - st->mem2 = strdup (str); - /* KEY must be a managing key. */ - mtext_put_prop (mt, 0, mtext_len (mt), key, st); - /* This sets the reference count of ST back to 1. */ - m17n_object_unref (st); -} -#endif - -void * -m17n_object (int size, void (*freer) (void *)) -{ - M17NObject *obj = malloc (size); - - obj->ref_count = 1; - obj->u.freer = freer; - return obj; -} - -/*=*/ - -/***en - @brief Increment the reference count of a managed object. - - The m17n_object_ref () function increments the reference count of - the managed object pointed to by $OBJECT. - - @return - This function returns the resulting reference count if it fits in - a 16-bit unsigned integer (i.e. less than 0x10000). Otherwise, it - return -1. - - @errors - This function never fails. */ - -int -m17n_object_ref (void *object) -{ - M17NObject *obj = (M17NObject *) object; - M17NObjectRecord *record; - unsigned *count; - - if (! obj->ref_count_extended) - { - if (++obj->ref_count) - return (int) obj->ref_count; - MSTRUCT_MALLOC (record, MERROR_OBJECT); - record->freer = obj->u.freer; - MLIST_INIT1 (record, counts, 1); - MLIST_APPEND1 (record, counts, 0, MERROR_OBJECT); - obj->u.record = record; - obj->ref_count_extended = 1; - } - else - record = obj->u.record; - - count = record->counts; - while (*count == 0xFFFFFFFF) - *(count++) = 0; - (*count)++; - if (*count == 0xFFFFFFFF) - MLIST_APPEND1 (record, counts, 0, MERROR_OBJECT); - return -1; -} - -/*=*/ - -/***en - @brief Decrement the reference count of a managed object. - - The m17n_object_unref () function decrements the reference count - of the managed object pointed to by $OBJECT. When the reference - count becomes zero, the object is freed by its freer function. - - @return - This function returns the resulting reference count if it fits in - a 16-bit unsigned integer (i.e. less than 0x10000). Otherwise, it - returns -1. Thus, the return value zero means that $OBJECT is - freed. - - @errors - This function never fails. */ - -int -m17n_object_unref (void *object) -{ - M17NObject *obj = (M17NObject *) object; - M17NObjectRecord *record; - unsigned *count; - - if (! obj->ref_count_extended) - { - if (! --obj->ref_count) - { - if (obj->u.freer) - (obj->u.freer) (object); - else - free (object); - return 0; - } - return (int) obj->ref_count; - } - - record = obj->u.record; - count = record->counts; - while (! *count) - *(count++) = 0xFFFFFFFF; - (*count)--; - if (! record->counts[0]) - { - obj->ref_count_extended = 0; - obj->ref_count--; - obj->u.freer = record->freer; - MLIST_FREE1 (record, counts); - free (record); - } - return -1; -} - -/*=*/ - -/*** @} */ - -/***en - @addtogroup m17nError Error handling - @brief Error handling of the m17n library. - - There are two types of errors that may happen in a function of - the m17n library. - - The first type is argument errors. When a library function is - called with invalid arguments, it returns a value that indicates - error and at the same time sets the external variable @e - merror_code to a non-zero integer. - - The second type is memory allocation errors. When the required - amount of memory is not available on the system, m17n library - functions call a function pointed to by the external variable @c - m17n_memory_full_handler. The default value of the variable is a - pointer to the default_error_handle () function, which just calls - exit (). */ - -/***ja - @addtogroup m17nError ¥¨¥é¡¼½èÍý - @brief m17n ¥é¥¤¥Ö¥é¥ê¤Î¥¨¥é¡¼½èÍý - - m17n ¥é¥¤¥Ö¥é¥ê¤Î´Ø¿ô¤Ç¤Ï¡¢£²¤Ä¤Î¼ïÎà¤Î¥¨¥é¡¼¤¬µ¯¤³¤êÆÀ¤ë¡£ - - °ì¤Ä¤Ï°ú¿ô¤Î¥¨¥é¡¼¤Ç¤¢¤ë¡£¥é¥¤¥Ö¥é¥ê¤Î´Ø¿ô¤¬ÂÅÅö¤Ç¤Ê¤¤°ú¿ô¤È¤È¤â¤Ë - ¸Æ¤Ð¤ì¤¿¾ì¹ç¡¢¤½¤Î´Ø¿ô¤Ï¥¨¥é¡¼¤ò°ÕÌ£¤¹¤ëÃͤòÊÖ¤·¡¢Æ±»þ¤Ë³°ÉôÊÑ¿ô - #merror_code ¤Ë¥¼¥í¤Ç¤Ê¤¤À°¿ô¤ò¥»¥Ã¥È¤¹¤ë¡£ - - ¤â¤¦°ì¤Ä¤Î¼ïÎà¤Ï¥á¥â¥ê³äÅö¤Æ¥¨¥é¡¼¤Ç¤¢¤ë¡£¥·¥¹¥Æ¥à¤¬É¬ÍפÊÎ̤Υá¥â - ¥ê¤ò³äÅö¤Æ¤ë¤³¤È¤¬¤Ç¤­¤Ê¤¤¾ì¹ç¡¢¥é¥¤¥Ö¥é¥ê´Ø¿ô¤Ï³°ÉôÊÑ¿ô @c - m17n_memory_full_handler ¤¬»Ø¤¹´Ø¿ô¤ò¸Æ¤Ö¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢Ã±¤Ë - exit () ¤ò¸Æ¤Ö¤³¤È¤Ë¤Ê¤Ã¤Æ¤¤¤ë¡£ -*/ - -/*** @{ */ - -/*=*/ - -/***en @brief External variable to hold error code of the m17n library - - The external variable #merror_code holds an error code of the - m17n library. When a library function is called with an invalid - argument, it sets this variable to one of @c enum #MErrorCode. - - This variable initially has the value 0. */ - -/***ja @brief m17n ¥é¥¤¥Ö¥é¥ê¤Î¥¨¥é¡¼¥³¡¼¥É¤òÊÝ»ý¤¹¤ë³°ÉôÊÑ¿ô - - ³°ÉôÊÑ¿ô #merror_code ¤Ï¡¢m17n ¥é¥¤¥Ö¥é¥ê¤Î¥¨¥é¡¼¥³¡¼¥É¤òÊÝ»ý¤¹¤ë¡£ - ¥é¥¤¥Ö¥é¥ê´Ø¿ô¤¬ÂÅÅö¤Ç¤Ê¤¤°ú¿ô¤È¤È¤â¤Ë¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ - ¤³¤ÎÊÑ¿ô¤ò @c enum #MErrorCode ¤Î°ì¤Ä¤Ë¥»¥Ã¥È¤¹¤ë¡£ - - ¤³¤ÎÊÑ¿ô¤Î½é´üÃͤϣ°¤Ç¤¢¤ë¡£ */ - -enum MErrorCode merror_code; - -/*=*/ - -/***en @brief Memory allocation error handler - - The external variable #m17n_memory_full_handler holds a pointer - to the function to call when a library function failed to allocate - memory. $ERR is one of @c enum #MErrorCode indicating in which - function the error occurred. - - This variable initially points a function that simply calls the - exit () function with $ERR as an argument. - - An application program that needs a different error handling can - change this variable to point a proper function. */ - -/***ja @brief ¥á¥â¥ê³äÅö¤Æ¥¨¥é¡¼¥Ï¥ó¥É¥é - - ÊÑ¿ô #m17n_memory_full_handler ¤Ï¡¢¥é¥¤¥Ö¥é¥ê´Ø¿ô¤¬¥á¥â¥ê³äÅö¤Æ - ¤Ë¼ºÇÔ¤·¤¿ºÝ¤Ë¸Æ¤Ö¤Ù¤­´Ø¿ô¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£$ERR ¤Ï @c enum - #MErrorCode ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ê¡¢¤É¤Î¥é¥¤¥Ö¥é¥ê´Ø¿ô¤Ç¥¨¥é¡¼¤¬µ¯¤Ã¤¿ - ¤«¤ò¼¨¤¹¡£ - - @anchor test - - ½é´üÀßÄê¤Ç¤Ï¡¢¤³¤ÎÊÑ¿ô¤Ïñ¤Ë exit () ¤ò $ERR ¤ò°ú¿ô¤È¤·¤Æ - ¸Æ¤Ö´Ø¿ô¤ò»Ø¤·¤Æ¤¤¤ë¡£ - - ¤³¤ì¤È¤Ï°Û¤Ê¤ë¥¨¥é¡¼½èÍý¤òɬÍפȤ¹¤ë¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Ï¡¢¤³¤ÎÊÑ¿ô¤ò - ŬÅö¤Ê´Ø¿ô¤ËÀßÄꤹ¤ë¤³¤È¤Ç¡¢ÌÜŪ¤òãÀ®¤Ç¤­¤ë¡£ */ - -void (*m17n_memory_full_handler) (enum MErrorCode err); - -/*** @} */ - -/*=*/ - -/***en - @addtogroup m17nDebug - @brief Support for m17n library users to debug their programs. - - The m17n library provides the following facilities to support the - library users to debug their programs. - -
    - -
  • Environment variables to control printing of various - information. - -
      - -
    • MDEBUG_INIT -- If set to 1, print information about the - library initialization on the call of M17N_INIT (). - -
    • MDEBUG_FINI -- If set to 1, print counts of objects that are - not yet freed on the call of M17N_FINI (). - -
    • MDEBUG_CHARSET -- If set to 1, print information about - charsets being loaded from the m17n database. - -
    • MDEBUG_CODING -- If set to 1, print information about coding - systems being loaded from the m17n database. - -
    • MDEBUG_DATABASE -- If set to 1, print information about - data being loaded from the m17n database. - -
    • MDEBUG_FONT -- If set to 1, print information about fonts - being selected and opened. - -
    • MDEBUG_FONT_FLT -- If set to 1, print information about which - command of Font Layout Table are being executed. - -
    • MDEBUG_FONT_OTF -- If set to 1, print information about which - feature of OpenType Layout Table are being executed. - -
    • MDEBUG_INPUT -- If set to 1, print information about how an - input method is running. - -
    • MDEBUG_ALL -- Setting this variable to 1 is equivalent to - setting all the above variables to 1. - -
    - -
  • Functions to print various objects in a human readable way. - See the documentation of mdebug_dump_XXXX () functions. - -
  • The hook function called on an error. See the documentation - of mdebug_hook (). - -
-*/ - -/*=*/ -/*** @{ */ -/*=*/ - -/***en - @brief Hook function called on an error. - - The mdebug_hook () function is called when an error happens. It - returns -1q without doing anything. It is useful to set a break - point on this function in a debugger. */ - -int -mdebug_hook () -{ - return -1; -} - -/*=*/ - -/*** @} */ - -/* - Local Variables: - coding: euc-japan - End: -*/ diff --git a/src/m17n-core.h b/src/m17n-core.h deleted file mode 100644 index f401456..0000000 --- a/src/m17n-core.h +++ /dev/null @@ -1,529 +0,0 @@ -/* m17n-core.h -- header file for the CORE API of the m17n library. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -#ifndef _M17N_CORE_H_ -#define _M17N_CORE_H_ - -#ifdef __cplusplus -extern "C" -{ -#endif - -/* - * Header file for m17n library. - */ - -/* (C1) Introduction */ - -/***en @defgroup m17nIntro Introduction */ -/***ja @defgroup m17nIntro ¤Ï¤¸¤á¤Ë */ -/*=*/ - -#define M17NLIB_MAJOR_VERSION 1 -#define M17NLIB_MINOR_VERSION 0 -#define M17NLIB_VERSION_NAME "1.0" - -extern void m17n_init_core (void); -#define M17N_INIT() m17n_init_core () -extern void m17n_fini_core (void); -#define M17N_FINI() m17n_fini_core () - -/***en @defgroup m17nCore CORE API */ -/***ja @defgroup m17nCore CORE API */ -/*=*/ -/*** @ingroup m17nCore */ -/***en @defgroup m17nObject Managed Object */ -/***ja @defgroup m17nObject ´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È */ -/*=*/ - -/*** @ingroup m17nObject */ -/***en - @brief The first member of a managed object. - - When an application program defines a new structure for managed - objects, its first member must be of the type @c struct - #M17NObjectHead. Its contents are used by the m17n library, and - application programs should never touch them. */ - -typedef struct -{ - void *filler[2]; -} M17NObjectHead; - -/*=*/ - -/* Return a newly allocated managed object. */ -extern void *m17n_object_setup (int size, void (*freer) (void *)); - -/* Increment the reference count of managed object OBJECT. */ -extern int m17n_object_ref (void *object); - -/* Decrement the reference count of managed object OBJECT. */ -extern int m17n_object_unref (void *object); - -/*=*/ - -/* (C2) Symbol handling */ - -/*** @ingroup m17nCore */ -/***en @defgroup m17nSymbol Symbol */ -/***ja @defgroup m17nSymbol ¥·¥ó¥Ü¥ë */ -/*=*/ - -/*** - @ingroup m17nSymbol */ -/***en - @brief Type of symbols. - - The type #MSymbol is for a @e symbol object. Its internal - structure is concealed from application programs. */ - -/***ja - @brief ¥·¥ó¥Ü¥ë¤Î·¿ - - #MSymbol ¤Ï¥·¥ó¥Ü¥ë¥ª¥Ö¥¸¥§¥¯¥È¤Î·¿¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£ */ - -typedef struct MSymbol *MSymbol; - -/*=*/ - -/* Predefined symbols. */ -extern MSymbol Mnil; -extern MSymbol Mt; -extern MSymbol Mstring; -extern MSymbol Msymbol; -extern MSymbol Mtext; - -/* Return a symbol of name NAME. */ -extern MSymbol msymbol (const char *name); - -/* Return a managing key of name NAME. */ -extern MSymbol msymbol_as_managing_key (const char *name); - -/* Return a symbol of name NAME if it already exists. */ -extern MSymbol msymbol_exist (const char *name); - -/* Return the name of SYMBOL. */ -extern char *msymbol_name (MSymbol symbol); - -/* Give SYMBOL KEY property with value VALUE. */ -extern int msymbol_put (MSymbol symbol, MSymbol key, void *val); - -/*** Return KEY property value of SYMBOL. */ -extern void *msymbol_get (MSymbol symbol, MSymbol key); - -/* - * (2-1) Property List - */ - -/*** @ingroup m17nCore */ -/***en @defgroup m17nPlist Property List */ -/***ja @defgroup m17nPlist ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¡¦¥ª¥Ö¥¸¥§¥¯¥È */ -/*=*/ - -/*** - @ingroup m17nPlist */ -/***en - @brief Type of property list objects. - - The type #MPlist is for a property list object. Its internal - structure is concealed from application programs. */ - -typedef struct MPlist MPlist; - -/*=*/ - -extern MSymbol Mplist, Minteger; - -extern MPlist *mplist (); - -extern MPlist *mplist_copy (MPlist *plist); - -extern MPlist *mplist_add (MPlist *plist, MSymbol key, void *val); - -extern MPlist *mplist_push (MPlist *plist, MSymbol key, void *val); - -extern void *mplist_pop (MPlist *plist); - -extern MPlist *mplist_put (MPlist *plist, MSymbol key, void *val); - -extern void *mplist_get (MPlist *plist, MSymbol key); - -extern MPlist *mplist_find_by_key (MPlist *plist, MSymbol key); - -extern MPlist *mplist_find_by_value (MPlist *plist, void *val); - -extern MPlist *mplist_next (MPlist *plist); - -extern MPlist *mplist_set (MPlist *plist, MSymbol key, void *val); - -extern int mplist_length (MPlist *plist); - -extern MSymbol mplist_key (MPlist *plist); - -extern void *mplist_value (MPlist *plist); - -/* (S1) Characters */ - -/*=*/ -/*** @ingroup m17nCore */ -/***en @defgroup m17nCharacter Character */ -/***ja @defgroup m17nCharacter ʸ»ú */ -/*=*/ - -#define MCHAR_MAX 0x3FFFFF -/*#define MCHAR_MAX 0x7FFFFFFF*/ - -extern MSymbol Mscript; -extern MSymbol Mname; -extern MSymbol Mcategory; -extern MSymbol Mcombining_class; -extern MSymbol Mbidi_category; -extern MSymbol Msimple_case_folding; -extern MSymbol Mcomplicated_case_folding; - -extern MSymbol mchar_define_property (char *name, MSymbol type); - -extern void *mchar_get_prop (int c, MSymbol key); - -extern int mchar_put_prop (int c, MSymbol key, void *val); - -/* (C3) Handling chartable */ - -/*** @ingroup m17nCore */ -/***en @defgroup m17nChartable Chartable */ -/***ja @defgroup m17nChartable ʸ»ú¥Æ¡¼¥Ö¥ë */ -/*=*/ -extern MSymbol Mchar_table; - -/*** - @ingroup m17nChartable */ -/***en - @brief Type of chartables. - - The type #MCharTable is for a @e chartable objects. Its - internal structure is concealed from application programs. */ - -/***ja - @brief ʸ»ú¥Æ¡¼¥Ö¥ë¤Î·¿ - - #MCharTable ·¿¤Ï @e ʸ»ú¥Æ¡¼¥Ö¥ë ¥ª¥Ö¥¸¥§¥¯¥ÈÍѤι½Â¤ÂΤǤ¢¤ë¡£ - ÆâÉô¹½Â¤¤Ï¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤«¤é¤Ï¸«¤¨¤Ê¤¤¡£ */ - -typedef struct MCharTable MCharTable; -/*=*/ - -extern MCharTable *mchartable (MSymbol key, void *default_value); - -extern void *mchartable_lookup (MCharTable *table, int c); - -extern int mchartable_set (MCharTable *table, int c, void *val); - -extern int mchartable_set_range (MCharTable *table, int from, int to, - void *val); - -extern int mchartable_map (MCharTable *table, void *ignore, - void (*func) (int from, int to, - void *val, void *arg), - void *func_arg); - -extern void mchartable_range (MCharTable *table, int *from, int *to); - -/* - * (5) Handling M-text. - * "M" of M-text stands for: - * o Multilingual - * o Metamorphic - * o More than string - */ - -/*** @ingroup m17nCore */ -/***en @defgroup m17nMtext M-text */ -/***ja @defgroup m17nMtext M-text */ -/*=*/ - -/* - * (5-1) M-text basics - */ - -/*** @ingroup m17nMtext */ -/***en - @brief Type of @e M-texts. - - The type #MText is for an @e M-text object. Its internal - structure is concealed from application programs. */ - -/***ja - @brief @e MText Íѹ½Â¤ÂÎ - - #Mtext ¹½Â¤ÂÎ¤Ï @e M-text ¥ª¥Ö¥¸¥§¥¯¥È¤ËÍѤ¤¤é¤ì¤ë¡£ÆâÉô¹½Â¤¤Ï¥¢ - ¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤«¤é¤Ï¸«¤¨¤Ê¤¤¡£ - - @latexonly \IPAlabel{MText} @endlatexonly - @latexonly \IPAlabel{MText->MPlist} @endlatexonly */ - -typedef struct MText MText; - -/*=*/ - -extern MText *mtext (); - -/*=*/ - -/***en - @brief Enumeration for specifying the format of an M-text. - - The enum #MTextFormat is used as an argument of the - mtext_from_data () function to specify the format of data from - which an M-text is created. */ - -enum MTextFormat - { - MTEXT_FORMAT_US_ASCII, - MTEXT_FORMAT_UTF_8, - MTEXT_FORMAT_UTF_16LE, - MTEXT_FORMAT_UTF_16BE, - MTEXT_FORMAT_UTF_32LE, - MTEXT_FORMAT_UTF_32BE, - MTEXT_FORMAT_MAX - }; -/*=*/ - -extern MText *mtext_from_data (void *data, int nitems, - enum MTextFormat format); - - -/*=*/ - -/* - * (5-2) Functions to manipulate M-texts. They correspond to string - * manipulating functions in libc. - * In the following functions, mtext_XXX() corresponds to strXXX(). - */ - -extern int mtext_len (MText *mt); - -extern int mtext_ref_char (MText *mt, int pos); - -extern int mtext_set_char (MText *mt, int pos, int c); - -extern MText *mtext_copy (MText *mt1, int pos, MText *mt2, int from, int to); - -extern int mtext_compare (MText *mt1, int from1, int to1, - MText *mt2, int from2, int to2); - -extern int mtext_case_compare (MText *mt1, int from1, int to1, - MText *mt2, int from2, int to2); - -extern int mtext_character (MText *mt, int from, int to, int c); - -extern int mtext_del (MText *mt, int from, int to); - -extern int mtext_ins (MText *mt1, int pos, MText *mt2); - -extern int mtext_ins_char (MText *mt, int pos, int c, int n); - -extern MText *mtext_cat_char (MText *mt, int c); - -extern MText *mtext_duplicate (MText *mt, int from, int to); - -extern MText *mtext_dup (MText *mt); - -extern MText *mtext_cat (MText *mt1, MText *mt2); - -extern MText *mtext_ncat (MText *mt1, MText *mt2, int n); - -extern MText *mtext_cpy (MText *mt1, MText *mt2); - -extern MText *mtext_ncpy (MText *mt1, MText *mt2, int n); - -extern int mtext_chr (MText *mt, int c); - -extern int mtext_rchr (MText *mt, int c); - -extern int mtext_cmp (MText *mt1, MText *mt2); - -extern int mtext_ncmp (MText *mt1, MText *mt2, int n); - -extern int mtext_spn (MText *mt1, MText *mt2); - -extern int mtext_cspn (MText *mt1, MText *mt2); - -extern int mtext_pbrk (MText *mt1, MText *mt2); - -extern int mtext_text (MText *mt1, int pos, MText *mt2); - -extern int mtext_search (MText *mt1, int from, int to, MText *mt2); - -extern MText *mtext_tok (MText *mt, MText *delim, int *pos); - -extern int mtext_casecmp (MText *mt1, MText *mt2); - -extern int mtext_ncasecmp (MText *mt1, MText *mt2, int n); - -/* - * (5-3) Text properties - */ - -/*** @ingroup m17nCore */ -/***en @defgroup m17nTextProperty Text Property */ -/***ja @defgroup m17nTextProperty ¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£ */ -/*=*/ -/*** @ingroup m17nTextProperty */ -/***en - @brief Flag bits to control text property. - - The mtext_property () funciton accepts logical OR of these flag - bits as an argument. They control the behaviour of the created - text property as described in the documentation of each flag - bit. */ - -enum MTextPropertyControl - { - /***en If this flag bit is on, an M-text inserted at the start - position or at the middle of the text property inherits the - text property. */ - MTEXTPROP_FRONT_STICKY = 0x01, - - /***en If this flag bit is on, an M-text inserted at the end - position or at the middle of the text property inherits the - text property. */ - MTEXTPROP_REAR_STICKY = 0x02, - - /***en If this flag bit is on, the text property is removed if a - text in its region is modified. */ - MTEXTPROP_VOLATILE_WEAK = 0x04, - - /***en If this flag bit is on, the text property is removed if a - text or the other text property in its region is modified. */ - MTEXTPROP_VOLATILE_STRONG = 0x08, - - /***en If this flag bit is on, the text property is not - automatically merged with the others. */ - MTEXTPROP_NO_MERGE = 0x10, - - MTEXTPROP_CONTROL_MAX = 0x1F - }; - -/*=*/ -extern MSymbol Mtext_prop_serializer; -extern MSymbol Mtext_prop_deserializer; - - -/*** @ingroup m17nTextProperty */ -/***en - @brief Type of serializer functions. - - This is the type of serializer functions. If the key of a symbol - property is #Msymbol_prop_serializer, the value must be of this - type. - - @seealso Mtext_prop_serialize (), Mtext_prop_serializer -*/ - -typedef MPlist *(*MTextPropSerializeFunc) (void *val); - -/*** @ingroup m17nTextProperty */ -/***en - @brief Type of deserializer functions. - - This is the type of deserializer functions. If the key of a - symbol property is #Msymbol_prop_deserializer, the value must be - of this type. - - @seealso Mtext_prop_deserialize (), Mtext_prop_deserializer -*/ -typedef void *(*MTextPropDeserializeFunc) (MPlist *plist); - -extern void *mtext_get_prop (MText *mt, int pos, MSymbol key); - -extern int mtext_get_prop_values (MText *mt, int pos, MSymbol key, - void **values, int num); - -extern int mtext_get_prop_keys (MText *mt, int pos, MSymbol **keys); - -extern int mtext_put_prop (MText *mt, int from, int to, - MSymbol key, void *val); - -extern int mtext_put_prop_values (MText *mt, int from, int to, - MSymbol key, void **values, int num); - -extern int mtext_push_prop (MText *mt, int from, int to, - MSymbol key, void *val); - -extern int mtext_pop_prop (MText *mt, int from, int to, - MSymbol key); - -extern int mtext_change_prop (MText *mt, int from, int to, - MSymbol key, - int (*func) (int, void ***, int *)); - -extern int mtext_prop_range (MText *mt, MSymbol key, int pos, - int *from, int *to, int deeper); - -/*=*/ -typedef struct MTextProperty MTextProperty; - -/*=*/ - -extern MTextProperty *mtext_property (MSymbol key, void *val, - int control_bits); - -extern MText *mtext_property_mtext (MTextProperty *prop); - -extern MSymbol mtext_property_key (MTextProperty *prop); - -extern void *mtext_property_value (MTextProperty *prop); - -extern int mtext_property_start (MTextProperty *prop); - -extern int mtext_property_end (MTextProperty *prop); - -extern MTextProperty *mtext_get_property (MText *mt, int pos, MSymbol key); - -extern int mtext_get_properties (MText *mt, int pos, MSymbol key, - MTextProperty **props, int num); - -extern int mtext_attach_property (MText *mt, int from, int to, - MTextProperty *prop); - -extern int mtext_detach_property (MTextProperty *prop); - -extern int mtext_push_property (MText *mt, int from, int to, - MTextProperty *prop); - -extern MText *mtext_serialize (MText *mt, int from, int to, - MPlist *property_list); - -extern MText *mtext_deserialize (MText *mt); - -#ifdef __cplusplus -} -#endif - -#endif /* _M17N_CORE_H_ */ - -/* - Local Variables: - coding: euc-japan - End: -*/ diff --git a/src/m17n-misc.h b/src/m17n-misc.h deleted file mode 100644 index 8e6d7a3..0000000 --- a/src/m17n-misc.h +++ /dev/null @@ -1,123 +0,0 @@ -/* m17n-misc.h -- header file for the MISC API. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -#ifndef _M17N_ERR_H_ -#define _M17N_ERR_H_ - -/*** @defgroup m17nMisc MISC API */ -/*=*/ -/*** @ingroup m17nMisc */ -/***en @defgroup m17nError Error Handling */ -/***ja @defgroup m17nError ¥¨¥é¡¼½èÍý */ -/*=*/ - -/*** @ingroup m17nError */ -/***en - @brief Enumeration for error code of the m17n library. - - Enumeration for error code of the m17n library. - - When a library function is called with an invalid argument, it - sets the external variable @e merror_code to one of these values. - All the error codes are positive integers. - - When a memory allocation error happens, the function pointed to by - the external variable #m17n_memory_full_handler is called with one - of these values as an argument. */ - -/***ja - @brief m17n ¥é¥¤¥Ö¥é¥ê¥¨¥é¡¼¥³¡¼¥É¤ÎÎóµó - - m17n ¥é¥¤¥Ö¥é¥ê¥¨¥é¡¼¥³¡¼¥É¤ÎÎóµó - - ¥é¥¤¥Ö¥é¥ê¤Î´Ø¿ô¤¬ÂÅÅö¤Ç¤Ê¤¤°ú¿ô¤È¤È¤â¤Ë¸Æ¤Ð¤ì¤¿¾ì¹ç¤Ë¤Ï¡¢ÊÑ¿ô @c - merror_code ¤ò¤³¤ì¤é¤ÎÃͤΤɤ줫¤Ë¥»¥Ã¥È¤¹¤ë¡£¤¹¤Ù¤Æ¤Î¥¨¥é¡¼¥³¡¼¥É - ¤ÏÀµ¤ÎÀ°¿ô¤Ç¤¢¤ë¡£ - - ¥á¥â¥ê³äÅö¤Æ¥¨¥é¡¼¤ÎºÝ¤Ë¤Ï¡¢³°ÉôÊÑ¿ô #m17n_memory_full_handler ¤Î»Ø - ¤¹´Ø¿ô¤¬¡¢¤³¤ì¤é¤ÎÃͤΤ¦¤Á¤Î¤É¤ì¤«¤ò°ú¿ô¤È¤·¤Æ¸Æ¤Ð¤ì¤ë¡£ - */ - -enum MErrorCode - { - MERROR_NONE, - MERROR_OBJECT, - MERROR_SYMBOL, - MERROR_MTEXT, - MERROR_TEXTPROP, - MERROR_CHAR, - MERROR_CHARTABLE, - MERROR_CHARSET, - MERROR_CODING, - MERROR_RANGE, - MERROR_LANGUAGE, - MERROR_LOCALE, - MERROR_PLIST, - MERROR_MISC, - MERROR_WIN, - MERROR_X, - MERROR_FRAME, - MERROR_FACE, - MERROR_DRAW, - MERROR_FONT, - MERROR_FONTSET, - MERROR_FONT_OTF, - MERROR_FONT_FT, - MERROR_IM, - MERROR_DB, - MERROR_IO, - MERROR_DEBUG, - MERROR_MEMORY, - MERROR_MAX - }; - -/*=*/ - -extern enum MErrorCode merror_code; - -extern void (*m17n_memory_full_handler) (enum MErrorCode err); - -/*=*/ -/*** @ingroup m17nMisc */ -/***en @defgroup m17nDebug Debugging */ -/***ja @defgroup m17nDebug ¥Ç¥Ð¥Ã¥°¥µ¥Ý¡¼¥È */ -/*=*/ - -extern int mdebug_hook (void); - -extern MSymbol mdebug_dump_symbol (MSymbol sym, int indent); -extern MSymbol mdebug_dump_all_symbols (int indent); -extern MPlist *mdebug_dump_plist (MPlist *plist, int indent); -extern MText *mdebug_dump_mtext (MText *mt, int fullp, int indent); -extern MCharTable *mdebug_dump_chartab (MCharTable *table, int indent); - -#ifdef DOXYGEN_INTERNAL_MODULE -/***en @defgroup m17nInternal Internal */ -/***ja @defgroup m17nInternal Internal */ -#endif -#endif /* _M17N_ERR_H_ */ - -/* - Local Variables: - coding: euc-japan - End: -*/ diff --git a/src/m17n.c b/src/m17n.c deleted file mode 100644 index 0b658d0..0000000 --- a/src/m17n.c +++ /dev/null @@ -1,122 +0,0 @@ -/* m17n.c -- body of the SHELL API. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -#include -#include - -#include "m17n.h" -#include "m17n-misc.h" -#include "internal.h" -#include "charset.h" -#include "coding.h" - -static int shell_initialized; - - -/* Internal API */ - - -/* External API */ - -void -m17n_init (void) -{ - int mdebug_mask = MDEBUG_INIT; - - if (shell_initialized) - return; - m17n_init_core (); - if (merror_code < 0) - return; - MDEBUG_PUSH_TIME (); - MDEBUG_PUSH_TIME (); - if (mcharset__init () < 0) - goto err; - MDEBUG_PRINT_TIME ("INIT", (stderr, " to initialize charset module.")); - if (mcoding__init () < 0) - goto err; - MDEBUG_PRINT_TIME ("INIT", (stderr, " to initialize conv module.")); - if (mdatabase__init () < 0) - goto err; - MDEBUG_PRINT_TIME ("INIT", (stderr, " to initialize database module.")); - if (mcharset__load_from_database () < 0) - goto err; - MDEBUG_PRINT_TIME ("INIT", (stderr, " to load charset definitions.")); - if (mcoding__load_from_database () < 0) - goto err; - MDEBUG_PRINT_TIME ("INIT", (stderr, " to load coding definitions.")); - if (mchar__init () < 0) - goto err; - MDEBUG_PRINT_TIME ("INIT", (stderr, " to initialize character module.")); - if (mlang__init () < 0) - goto err; - MDEBUG_PRINT_TIME ("INIT", (stderr, " to initialize language module")); - if (mlocale__init () < 0) - goto err; - MDEBUG_PRINT_TIME ("INIT", (stderr, " to initialize locale module.")); - if (minput__init () < 0) - goto err; - MDEBUG_PRINT_TIME ("INIT", (stderr, " to initialize input module.")); - shell_initialized = 1; - - err: - MDEBUG_POP_TIME (); - MDEBUG_PRINT_TIME ("INIT", (stderr, " to initialize the shell modules.")); - MDEBUG_POP_TIME (); -} - -void -m17n_fini (void) -{ - int mdebug_mask = MDEBUG_FINI; - - if (shell_initialized) - { - MDEBUG_PUSH_TIME (); - MDEBUG_PUSH_TIME (); - MDEBUG_PRINT_TIME ("INIT", (stderr, " to finalize input module.")); - minput__fini (); - MDEBUG_PRINT_TIME ("INIT", (stderr, " to finalize locale module.")); - mlocale__fini (); - MDEBUG_PRINT_TIME ("INIT", (stderr, " to finalize language module.")); - mlang__fini (); - MDEBUG_PRINT_TIME ("INIT", (stderr, " to finalize character module.")); - mchar__fini (); - MDEBUG_PRINT_TIME ("INIT", (stderr, " to finalize database module.")); - mdatabase__fini (); - MDEBUG_PRINT_TIME ("INIT", (stderr, " to finalize coding module.")); - mcoding__fini (); - MDEBUG_PRINT_TIME ("INIT", (stderr, " to finalize charset module.")); - mcharset__fini (); - MDEBUG_POP_TIME (); - MDEBUG_PRINT_TIME ("INIT", (stderr, " to finalize the shell modules.")); - MDEBUG_POP_TIME (); - shell_initialized = 0; - } - m17n_fini_core (); -} - -/* - Local Variables: - coding: euc-japan - End: -*/ diff --git a/src/m17n.h b/src/m17n.h deleted file mode 100644 index c0e6c8f..0000000 --- a/src/m17n.h +++ /dev/null @@ -1,1257 +0,0 @@ -/* m17n.h -- header file for the SHELL API of the m17n library. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -#ifndef _M17N_H_ -#define _M17N_H_ - -#include -#include -#include - -#ifndef _M17N_CORE_H_ -#include -#endif - -#ifdef __cplusplus -extern "C" -{ -#endif - -extern void m17n_init (void); -#undef M17N_INIT -#define M17N_INIT() m17n_init () - -extern void m17n_fini (void); -#undef M17N_FINI -#define M17N_FINI() m17n_fini () - -/***en @defgroup m17nShell SHELL API */ -/***ja @defgroup m17nShell SHELL API */ -/*=*/ - -/* - * (11) Functions related to the m17n database - */ - -/*** @ingroup m17nShell */ -/***en @defgroup m17nDatabase Database */ -/***ja @defgroup m17nDatabase ¸À¸ì¾ðÊó¥Ç¡¼¥¿¥Ù¡¼¥¹ */ -/*=*/ -/* Directory of an application specific databases. */ -extern char *mdatabase_dir; - -/*** - @ingroup m17nDatabase */ -/***en - @brief Type of database. - - The type #MDatabase is for a database object. Its internal - structure is concealed from application programs. */ -/***ja ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Î·¿Àë¸À */ -typedef struct MDatabase MDatabase; - -/*=*/ - -/* Look for a data. */ -extern MDatabase *mdatabase_find (MSymbol tag1, MSymbol tag2, - MSymbol tag3, MSymbol tag4); - -extern MPlist *mdatabase_list (MSymbol tag0, MSymbol tag1, - MSymbol tag2, MSymbol tag3); - -/* Load a data. */ -void *mdatabase_load (MDatabase *mdb); - -/* Get tags of a data. */ -extern MSymbol *mdatabase_tag (MDatabase *mdb); - -/* Define a data. */ -extern MDatabase *mdatabase_define (MSymbol tag1, MSymbol tag2, - MSymbol tag3, MSymbol tag4, - void *(*loader) (MSymbol *, void *), - void *extra_info); - -/*=*/ -/* (S2) Charset staffs */ - -/*** @ingroup m17nShell */ -/***en @defgroup m17nCharset Charset */ -/***ja @defgroup m17nCharset ʸ»ú¥»¥Ã¥È */ -/*=*/ -#define MCHAR_INVALID_CODE 0xFFFFFFFF - -/* Predefined charsets */ -extern MSymbol Mcharset_ascii; -extern MSymbol Mcharset_iso_8859_1; -extern MSymbol Mcharset_unicode; -extern MSymbol Mcharset_m17n; -extern MSymbol Mcharset_binary; - -/* Predefined keys for mchar_define_charset (). */ -extern MSymbol Mmethod; -extern MSymbol Mdimension; -extern MSymbol Mmin_range; -extern MSymbol Mmax_range; -extern MSymbol Mmin_code; -extern MSymbol Mmax_code; -extern MSymbol Mascii_compatible; -extern MSymbol Mfinal_byte; -extern MSymbol Mrevision; -extern MSymbol Mmin_char; -extern MSymbol Mmapfile; -extern MSymbol Mparents; -extern MSymbol Msubset_offset; -extern MSymbol Mdefine_coding; -extern MSymbol Maliases; - -/* Methods of a charset. */ -extern MSymbol Moffset; -extern MSymbol Mmap; -extern MSymbol Munify; -extern MSymbol Msubset; -extern MSymbol Msuperset; - -/* etc. */ -extern MSymbol Mcharset; - -extern MSymbol mchar_define_charset (char *name, MPlist *plist); - -extern MSymbol mchar_resolve_charset (MSymbol symbol); - -extern int mchar_list_charset (MSymbol **symbols); - -extern int mchar_decode (MSymbol charset_name, unsigned code); - -extern unsigned mchar_encode (MSymbol charset_name, int c); - -extern int mchar_map_charset (MSymbol charset_name, - void (*func) (int from, int to, void *arg), - void *func_arg); - -/*=*/ - -/* (S3) code conversion */ - -/*** @ingroup m17nShell */ -/***en @defgroup m17nConv Code Conversion */ -/***ja @defgroup m17nConv ¥³¡¼¥ÉÊÑ´¹ */ -/*=*/ - -/* Predefined coding systems */ -extern MSymbol Mcoding_us_ascii; -extern MSymbol Mcoding_iso_8859_1; -extern MSymbol Mcoding_utf_8; -extern MSymbol Mcoding_utf_8_full; -extern MSymbol Mcoding_utf_16; -extern MSymbol Mcoding_utf_16be; -extern MSymbol Mcoding_utf_16le; -extern MSymbol Mcoding_utf_32; -extern MSymbol Mcoding_utf_32be; -extern MSymbol Mcoding_utf_32le; -extern MSymbol Mcoding_sjis; - -/* Parameter keys for mconv_define_coding (). */ -extern MSymbol Mtype; -extern MSymbol Mcharsets; -extern MSymbol Mflags; -extern MSymbol Mdesignation; -extern MSymbol Minvocation; -extern MSymbol Mcode_unit; -extern MSymbol Mbom; -extern MSymbol Mlittle_endian; - -/* Symbols representing coding system type. */ -extern MSymbol Mutf; -extern MSymbol Miso_2022; - -/* Symbols appearing in the value of Mfrag parameter. */ -extern MSymbol Mreset_at_eol; -extern MSymbol Mreset_at_cntl; -extern MSymbol Meight_bit; -extern MSymbol Mlong_form; -extern MSymbol Mdesignation_g0; -extern MSymbol Mdesignation_g1; -extern MSymbol Mdesignation_ctext; -extern MSymbol Mdesignation_ctext_ext; -extern MSymbol Mlocking_shift; -extern MSymbol Msingle_shift; -extern MSymbol Msingle_shift_7; -extern MSymbol Meuc_tw_shift; -extern MSymbol Miso_6429; -extern MSymbol Mrevision_number; -extern MSymbol Mfull_support; - -/* etc */ -extern MSymbol Mcoding; -extern MSymbol Mmaybe; - -/*** @ingroup m17nConv */ -/***en - @brief Codes that represent the result of code conversion. - - One of these values is set in @c MConverter-\>result. */ - -/***ja - @brief ¥³¡¼¥ÉÊÑ´¹¤Î·ë²Ì¤ò¼¨¤¹¥³¡¼¥É - - ¤³¤ì¤é¤ÎÃͤΤ¦¤Á°ì¤Ä¤¬ @c MConverter-\>result ¤ËÀßÄꤵ¤ì¤ë¡£ */ - -enum MConversionResult - { - /***en Code conversion is successful. */ - /***ja ¥³¡¼¥ÉÊÑ´¹¤ÏÀ®¸ù¡£ */ - MCONVERSION_RESULT_SUCCESS, - - /***en On decoding, the source contains an invalid byte. */ - /***ja ¥Ç¥³¡¼¥É¤ÎºÝ¡¢¥½¡¼¥¹¤ËÉÔÀµ¤Ê¥Ð¥¤¥È¤¬´Þ¤Þ¤ì¤ë¡£ */ - MCONVERSION_RESULT_INVALID_BYTE, - - /***en On encoding, the source contains a character that cannot be - encoded by the specified coding system. */ - - /***ja ¥¨¥ó¥³¡¼¥É¤ÎºÝ¡¢¥½¡¼¥¹¤Ë»ØÄê¤Î¥³¡¼¥É·Ï¤Ç - ¥¨¥ó¥³¡¼¥É¤Ç¤­¤Ê¤¤Ê¸»ú¤¬´Þ¤Þ¤ì¤ë¡£ */ - MCONVERSION_RESULT_INVALID_CHAR, - - /***en On decoding, the source ends with an incomplete byte sequence. */ - /***ja ¥Ç¥³¡¼¥É¤ÎºÝ¡¢¥½¡¼¥¹¤¬ÉÔ´°Á´¤Ê¥Ð¥¤¥ÈÎó¤Ç½ª¤ï¤ë¡£*/ - MCONVERSION_RESULT_INSUFFICIENT_SRC, - - /***en On encoding, the destination is too short to store the result. */ - /***ja ¥¨¥ó¥³¡¼¥É¤ÎºÝ¡¢·ë²Ì¤ò³ÊǼ¤¹¤ëÎΰ褬û¤«¤¹¤®¤ë¡£ */ - MCONVERSION_RESULT_INSUFFICIENT_DST, - - /***en An I/O error occurred in the conversion. */ - /***ja ¥³¡¼¥ÉÊÑ´¹Ãæ¤Ë I/O ¥¨¥é¡¼¤¬µ¯¤³¤Ã¤¿¡£ */ - MCONVERSION_RESULT_IO_ERROR - }; -/*=*/ - -/*** @ingroup m17nConv */ -/***en - @brief Structure to be used in code conversion. - - The first three members are to control the conversion. */ - -/***ja - @brief ¥³¡¼¥ÉÊÑ´¹¤ËÍѤ¤¤é¤ì¤ë¹½Â¤ÂÎ - - @latexonly \IPAlabel{MConverter} @endlatexonly -*/ - -typedef struct -{ - /***en - Set the value to nonzero if the conversion should be lenient. - By default, the conversion is strict (i.e. not lenient). - - If the conversion is strict, the converter stops at the first - invalid byte (on decoding) or at the first character not - supported by the coding system (on encoding). If this happens, - @c MConverter-\>result is set to @c - MCONVERSION_RESULT_INVALID_BYTE or @c - MCONVERSION_RESULT_INVALID_CHAR accordingly. - - If the conversion is lenient, on decoding, an invalid byte is - kept per se, and on encoding, an invalid character is replaced - with "" (if the character is a Unicode character) or - with "" (otherwise). */ - - /***ja - ¸·Ì©¤ÊÊÑ´¹¤¬É¬ÍפǤʤ¤¾ì¹ç¤Ë¤³¤Î¥Õ¥é¥°¥Ó¥Ã¥È¤ò¤¿¤Æ¤ë¡£¥Ç¥Õ¥© - ¥ë¥È¤Ç¤Ï¡¢ÊÑ´¹¤Ï¸·Ì©¤Ç¤¢¤ë¡£ - - ÊÑ´¹¤¬¸·Ì©¤È¤Ï¡¢¥Ç¥³¡¼¥É¤ÎºÝ¤Ë¤ÏºÇ½é¤ÎÉÔÀµ¤Ê¥Ð¥¤¥È¤Ç¥³¥ó¥Ð¡¼¥¿ - ¤¬»ß¤Þ¤ë¤³¤È¡¢¥¨¥ó¥³¡¼¥É¤ÎºÝ¤Ë¤ÏÊÑ´¹¤µ¤ì¤ë¥³¡¼¥É·Ï¤Ç¥µ¥Ý¡¼¥È¤µ - ¤ì¤Ê¤¤ºÇ½é¤Îʸ»ú¤Ç¥³¥ó¥Ð¡¼¥¿¤¬»ß¤Þ¤ë¤³¤È¤ò»Ø¤¹¡£¤³¤ì¤é¤Î¾ì¹ç¡¢ - @c MConverter-\>result ¤Ï¤½¤ì¤¾¤ì@c - MCONVERSION_RESULT_INVALID_BYTE ¤«@c - MCONVERSION_RESULT_INVALID_CHAR ¤È¤Ê¤ë¡£ - - ÊÑ´¹¤¬¸·Ì©¤Ç¤Ê¤¤¾ì¹ç¤Ë¤Ï¡¢¥Ç¥³¡¼¥É¤ÎºÝ¤ÎÉÔÀµ¤Ê¥Ð¥¤¥È¤Ï¤½¤Î¥Ð¥¤ - ¥È¤Î¤Þ¤Þ»Ä¤ë¡£¤Þ¤¿¥¨¥ó¥³¡¼¥É¤ÎºÝ¤Ë¤Ï¡¢ÉÔÀµ¤Êʸ»ú¤Ï¥³¡¼¥É·Ï¤´¤È - ¤ËÄê¤á¤é¤ì¤¿¥Ç¥Õ¥©¥ë¥È¤Îʸ»ú¤ÈÃÖ¤­´¹¤¨¤é¤ì¤ë¡£ */ - - int lenient; - - /***en - Set the value to nonzero before decoding or encoding the last - block of the byte sequence or the character sequence - respectively. The value influences the conversion as below. - - On decoding, in the case that the last few bytes are too short - to form a valid byte sequence: - - If the value is nonzero, the conversion terminates by error - (MCONVERSION_RESULT_INVALID_BYTE) at the first byte of the - sequence. - - If the value is zero, the conversion terminates successfully. - Those bytes are stored in the converter as carryover and are - prepended to the byte sequence of the further conversion. - - On encoding, in the case that the coding system is context - dependent: - - If the value is nonzero, the conversion may produce a byte - sequence at the end to reset the context to the initial state - even if the source characters are zero. - - If the value is zero, the conversion never produce such a byte - sequence at the end. */ - - /***ja - ʸ»ú¥³¡¼¥ÉÎó¤Î½ªÃ¼Éôʬ¤ò¥¨¥ó¥³¡¼¥É¤¹¤ëºÝ¤Ë¤Ï¡¢¤³¤Î¥Õ¥é¥°¤òΩ¤Æ - ¤ë¡£¤³¤Î¾ì¹ç½ÐÎÏ¥³¡¼¥É¥Ý¥¤¥ó¥ÈÎó¤Î¥³¥ó¥Æ¥¯¥¹¥È¤ò¸µ¤ËÌ᤹¤¿¤á¤Î - ¿ô¥Ð¥¤¥È¤¬ÉÕ²ÃŪ¤ËÀ¸À®¤µ¤ì¤ë¤³¤È¤¬¤¢¤ë¡£ - - ¤³¤Î¥Õ¥é¥°¤Ï¥Ç¥Õ¥©¥ë¥È¤Ç¤ÏΩ¤Ã¤Æ¤ª¤é¤º¡¢¥³¥ó¥Ð¡¼¥¿¤Ï³¤±¤Æ¾¤Î - ʸ»ú¤ò¥¨¥ó¥³¡¼¥É¤¹¤ë¤â¤Î¤È²¾Äꤷ¤Æ¤¤¤ë¡£ - - ¤³¤Î¥Õ¥é¥°¤Ï¥Ç¥³¡¼¥É¤Ë¤Ï´Ø·¸¤·¤Ê¤¤¡£ */ - - int last_block; - - /***en - If the value is nonzero, it specifies at most how many - characters to convert. */ - - unsigned at_most; - - /***en - The following three members are to report the result of the - conversion. */ - - /***en - Number of characters most recently decoded or encoded. */ - - /***ja - ºÇ¸å¤Ë¥Ç¥³¡¼¥É/¥¨¥ó¥³¡¼¥É¤µ¤ì¤¿Ê¸»ú¿ô */ - - int nchars; - - /***en - Number of bytes recently decoded or encoded. */ - - /***ja - ºÇ¸å¤Ë¥Ç¥³¡¼¥É/¥¨¥ó¥³¡¼¥É¤µ¤ì¤¿¥Ð¥¤¥È¿ô */ - - int nbytes; - - /***en - Result code of the conversion. */ - - /***ja - ¥³¡¼¥ÉÊÑ´¹¤Î·ë²Ì¤ò¼¨¤¹¥³¡¼¥É */ - - enum MConversionResult result; - - /***en - Various information about the status of code conversion. The - contents depend on the type of coding system. It is assured - that @c status is aligned so that any type of casting is safe - and at least 256 bytes of memory space can be used. */ - - /***ja - ¥³¡¼¥ÉÊÑ´¹¤Î¾õ¶·¤Ë´Ø¤¹¤ë¾ðÊó¡£ÆâÍƤϥ³¡¼¥É·Ï¤Î¥¿¥¤¥×¤Ë¤è¤Ã¤Æ°Û¤Ê - ¤ë¡£@c status ¤Ï¤É¤Î¤è¤¦¤Ê·¿¤Ø¤Î¥­¥ã¥¹¥È¤ËÂФ·¤Æ¤â°ÂÁ´¤Ê¤è¤¦¤Ë¥á - ¥â¥ê¥¢¥é¥¤¥ó¤µ¤ì¤Æ¤ª¤ê¡¢¤Þ¤¿ºÇÄã256¥Ð¥¤¥È¤Î¥á¥â¥êÎΰ褬»È¤¨¤ë¤è - ¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤ë¡£ */ - - union { - void *ptr; - double dbl; - char c[256]; - } status; - - /***en - This member is for internally use only. An application program - should never touch it. */ - void *internal_info; -} MConverter; -/*=*/ - -/*** @ingroup m17nConv */ -/***en @brief Types of coding system */ -/***ja @brief ¥³¡¼¥É·Ï¤Î¥¿¥¤¥× */ - -enum MCodingType - { - /***en - A coding system of this type supports charsets directly. - The dimension of each charset defines the length of bytes to - represent a single character of the charset, and a byte - sequence directly represents the code-point of a character. - - The m17n library provides the default decoding and encoding - routines of this type. */ - - /***ja - ¤³¤Î¥¿¥¤¥×¤Î¥³¡¼¥É·Ï¤Ïʸ»ú¥»¥Ã¥È¤òľÀÜ¥µ¥Ý¡¼¥È¤¹¤ë¡£³Æʸ»ú¥»¥Ã - ¥È¤Î¼¡¸µ¤È¤Ï¡¢¤½¤Îʸ»ú¥»¥Ã¥È¤Ç°ìʸ»ú¤òɽ¸½¤¹¤ë¤¿¤á¤ËɬÍפʥХ¤ - ¥È¿ô¤Ç¤¢¤ê¡¢¥Ð¥¤¥ÈÎó¤Ïʸ»ú¤Î¥³¡¼¥É¥Ý¥¤¥ó¥È¤òľÀÜɽ¤ï¤¹¡£ - - m17n ¥é¥¤¥Ö¥é¥ê¤Ï¤³¤Î¥¿¥¤¥×ÍѤΥǥե©¥ë¥È¤Î¥¨¥ó¥³¡¼¥É¡¿¥Ç¥³¡¼ - ¥É¥ë¡¼¥Æ¥£¥ó¤òÄ󶡤¹¤ë¡£ */ - - MCODING_TYPE_CHARSET, - - /***en - A coding system of this type supports byte sequences of a - UTF (UTF-8, UTF-16, UTF-32) like structure. - - The m17n library provides the default decoding and encoding - routines of this type. */ - - /***ja - ¤³¤Î¥¿¥¤¥×¤Î¥³¡¼¥É·Ï¤Ï¡¢UTF ·Ï (UTF-8, UTF-16, UTF-32) ¤Î¥Ð¥¤ - ¥ÈÎó¤ò¥µ¥Ý¡¼¥È¤¹¤ë¡£ - - m17n ¥é¥¤¥Ö¥é¥ê¤Ï¤³¤Î¥¿¥¤¥×ÍѤΥǥե©¥ë¥È¤Î¥¨¥ó¥³¡¼¥É¡¿¥Ç¥³¡¼ - ¥É¥ë¡¼¥Æ¥£¥ó¤òÄ󶡤¹¤ë¡£ */ - - MCODING_TYPE_UTF, - - /***en - A coding system of this type supports byte sequences of an - ISO-2022 like structure. The details of each structure are - specified by @c MCodingInfoISO2022 . - - The m17n library provides decoding and encoding routines of - this type. */ - - /***ja - ¤³¤Î¥¿¥¤¥×¤Î¥³¡¼¥É·Ï¤Ï¡¢ISO-2022 ·Ï¤Î¥Ð¥¤¥ÈÎó¤ò¥µ¥Ý¡¼¥È¤¹¤ë¡£ - ¤³¤ì¤é¤Î¥³¡¼¥É·Ï¤Î¹½Â¤¤Î¾ÜºÙ¤Ï @c MCodingInfoISO2022 ¤Ç»ØÄꤵ - ¤ì¤ë¡£ - - m17n ¥é¥¤¥Ö¥é¥ê¤Ï¤³¤Î¥¿¥¤¥×ÍѤΥǥե©¥ë¥È¤Î¥¨¥ó¥³¡¼¥É¡¿¥Ç¥³¡¼ - ¥É¥ë¡¼¥Æ¥£¥ó¤òÄ󶡤¹¤ë¡£ */ - - MCODING_TYPE_ISO_2022, - - /***en - A coding system of this type is for byte sequences of - miscellaneous structures. - - The m17n library does not provide decoding and encoding - routines of this type. They must be provided by the - application program. */ - - /***ja - ¤³¤Î¥¿¥¤¥×¤Î¥³¡¼¥É·Ï¤Ï¡¢¤½¤Î¾¤Î¹½Â¤¤Î¥Ð¥¤¥ÈÎó¤Î¤¿¤á¤Î¤â¤Î¤Ç¤¢ - ¤ë¡£ - - m17n ¥é¥¤¥Ö¥é¥ê¤Ï¤³¤Î¥¿¥¤¥×ÍѤΥ¨¥ó¥³¡¼¥É¡¿¥Ç¥³¡¼¥É¥ë¡¼¥Æ¥£¥ó - ¤òÄ󶡤·¤Ê¤¤¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¦¤Ç¤½¤ì¤é¤ò½àÈ÷¤¹ - ¤ëɬÍפ¬¤¢¤ë¡£ */ - - MCODING_TYPE_MISC - }; -/*=*/ - -/*** @ingroup m17nConv */ -/***en @brief Bit-masks to specify the detail of coding system whose type is - MCODING_TYPE_ISO_2022. */ - -/***ja @brief MCODING_TYPE_ISO_2022 ¥¿¥¤¥×¤Î¥³¡¼¥É·Ï¤Î¾ÜºÙ¤òɽ¤ï¤¹¥Ó¥Ã¥È¥Þ¥¹ - ¥¯ */ - -enum MCodingFlagISO2022 - { - /***en - On encoding, reset the invocation and designation status to - initial at end of line. */ - /***ja ¥¨¥ó¥³¡¼¥É¤ÎºÝ¡¢¹ÔËö¤Ç¸Æ¤Ó½Ð¤· (invocation) ¤È»Ø¼¨ - (designation) ¤Î¾õÂÖ¤ò½é´üÃͤËÌ᤹¡£ */ - MCODING_ISO_RESET_AT_EOL = 0x1, - - /***en - On encoding, reset the invocation and designation status to - initial before any control codes. */ - /***ja - ¥¨¥ó¥³¡¼¥É¤ÎºÝ¡¢¤¹¤Ù¤Æ¤ÎÀ©¸æʸ»ú¤ÎÁ°¤Ç¡¢¸Æ¤Ó½Ð¤· - (invocation) ¤È»Ø¼¨ (designation) ¤Î¾õÂÖ¤ò½é´üÃͤËÌ᤹¡£ */ - MCODING_ISO_RESET_AT_CNTL = 0x2, - - /***en - Use the right graphic plane. */ - /***ja - ¿Þ·Áʸ»ú½¸¹ç¤Î±¦Â¦¤ò»È¤¦¡£ */ - MCODING_ISO_EIGHT_BIT = 0x4, - - /***en - Use the non-standard 4 bytes format for designation sequence - for charsets JISX0208.1978, GB2312, and JISX0208.1983. */ - /***ja - JISX0208.1978, GB2312, JISX0208.1983 ¤Îʸ»ú½¸¹ç¤ËÂФ¹¤ë»Ø¼¨¥·¡¼ - ¥¯¥¨¥ó¥¹¤È¤·¤Æ¡¢Èóɸ½à¤Î4¥Ð¥¤¥È·Á¼°¤òÍѤ¤¤ë¡£ */ - - MCODING_ISO_LONG_FORM = 0x8, - - /***en - On encoding, unless explicitly specified, designate charsets - to G0. */ - /***ja - ¥¨¥ó¥³¡¼¥É¤ÎºÝ¡¢Æä˻ØÄꤵ¤ì¤Ê¤¤¸Â¤ê¡¢Ê¸»ú½¸¹ç¤ò G0 ¤Ë - »Ø¼¨¤¹¤ë¡£*/ - MCODING_ISO_DESIGNATION_G0 = 0x10, - - /***en - On encoding, unless explicitly specified, designate charsets - except for ASCII to G1. */ - /***ja - ¥¨¥ó¥³¡¼¥É¤ÎºÝ¡¢Æä˻ØÄꤵ¤ì¤Ê¤¤¸Â¤ê¡¢ASCII °Ê³°¤Îʸ»ú½¸¹ç¤ò G1 - ¤Ë»Ø¼¨¤¹¤ë¡£*/ - MCODING_ISO_DESIGNATION_G1 = 0x20, - - /***en - On encoding, unless explicitly specified, designate 94-chars - charsets to G0, 96-chars charsets to G1. */ - /***ja - ¥¨¥ó¥³¡¼¥É¤ÎºÝ¡¢Æä˻ØÄꤵ¤ì¤Ê¤¤¸Â¤ê¡¢94ʸ»ú½¸¹ç¤ò G0 - ¤Ë¡¢96ʸ»ú½¸¹ç¤ò G1 ¤Ë»Ø¼¨¤¹¤ë¡£*/ - MCODING_ISO_DESIGNATION_CTEXT = 0x40, - - /***en - On encoding, encode such charsets not conforming to ISO-2022 - by ESC % / ..., and encode non-supported Unicode characters by - ESC % G ... ESC % @@ . On decoding, handle those escape - sequences. */ - /***ja - ¥¨¥ó¥³¡¼¥É¤ÎºÝ¡¢ISO-2022 ¤Ë¹çÃפ·¤Ê¤¤Ê¸»ú½¸¹ç¤ò ESC % / ... ¤Ç¥¨ - ¥ó¥³¡¼¥É¤¹¤ë¡£¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤¤ Unicode ʸ»ú¤Ï ESC % G ... - ESC % @@ ¤Ç¥¨¥ó¥³¡¼¥É¤¹¤ë¡£ - ¥Ç¥³¡¼¥É¤ÎºÝ¡¢¤³¤ì¤é¤Î¥¨¥¹¥±¡¼¥×¡¦¥·¡¼¥±¥ó¥¹¤ò²ò¼á¤¹¤ë¡£ */ - MCODING_ISO_DESIGNATION_CTEXT_EXT = 0x80, - - /***en - Use locking shift. */ - /***ja - ¥í¥Ã¥­¥ó¥°¥·¥Õ¥È¤ò»È¤¦¡£ */ - MCODING_ISO_LOCKING_SHIFT = 0x100, - - /***en - Use single shift (SS2 (0x8E or ESC N), SS3 (0x8F or ESC O)). */ - /***ja - ¥·¥ó¥°¥ë¥·¥Õ¥È (SS2 or ESC N) ¤ò»È¤¦¡£ */ - MCODING_ISO_SINGLE_SHIFT = 0x200, - - /***en - Use 7-bit single shift 2 (SS2 (0x19)). */ - /***ja - ¥·¥ó¥°¥ë¥·¥Õ¥È (0x19) ¤ò»È¤¦¡£ */ - MCODING_ISO_SINGLE_SHIFT_7 = 0x400, - - /***en - Use EUC-TW like special shifting. */ - /***ja - EUC-TW É÷¤ÎÆÃÊ̤ʥ·¥Õ¥È¤ò»È¤¦¡£ */ - MCODING_ISO_EUC_TW_SHIFT = 0x800, - - /***en - Use ISO-6429 escape sequences to indicate direction. - Not yet implemented. */ - /***ja - ISO-6429 ¤Î¥¨¥¹¥±¡¼¥×¥·¡¼¥¯¥¨¥ó¥¹¤ÇÊý¸þ¤ò»Ø¼¨¤¹¤ë¡£ */ - MCODING_ISO_ISO6429 = 0x1000, - - /***en - On encoding, if a charset has revision number, produce escape - sequences to specify the number. */ - /***ja - ¥¨¥ó¥³¡¼¥É¤ÎºÝ¡¢Ê¸»ú¥»¥Ã¥È¤Ë revision number ¤¬¤¢¤ì¤Ð¤½ - ¤ì¤òɽ¤ï¤¹¥¨¥¹¥±¡¼¥×¥·¡¼¥¯¥¨¥ó¥¹¤òÀ¸À®¤¹¤ë¡£ */ - MCODING_ISO_REVISION_NUMBER = 0x2000, - - /***en - Support all ISO-2022 charsets. */ - /***ja - ISO-2022 ¤ÎÁ´Ê¸»ú½¸¹ç¤ò¥µ¥Ý¡¼¥È¤¹¤ë */ - MCODING_ISO_FULL_SUPPORT = 0x3000, - - MCODING_ISO_FLAG_MAX - }; -/*=*/ - -/*** @ingroup m17nConv */ -/***en - @brief Structure for a coding system of type MCODING_TYPE_ISO_2022. - - Structure for extra information about a coding system of type - MCODING_TYPE_ISO_2022. */ - -/***ja - @brief MCODING_TYPE_ISO_2022 ¥¿¥¤¥×¤Î¥³¡¼¥É·Ï¤ÇɬÍ× - ¤ÊÉղþðÊóÍѹ½Â¤ÂÎ - - @latexonly \IPAlabel{MCodingInfoISO2022} @endlatexonly */ - -typedef struct -{ - /***en - Table of numbers of an ISO2022 code extension element invoked - to each graphic plane (Graphic Left and Graphic Right). -1 - means no code extension element is invoked to that plane. */ - - /***ja - ³Æ¿Þ·Áʸ»úÎΰè (Graphic Left ¤È Graphic Right) ¤Ë¸Æ¤Ó½Ð¤µ¤ì¤Æ¤¤ - ¤ë¡¢ISO2022 Éä¹ç³ÈÄ¥Í×ÁǤÎÈÖ¹æ¤Î¥Æ¡¼¥Ö¥ë¡£-1 ¤Ï¤½¤ÎÎΰè¤Ë¤É¤ÎÉä - ¹ç³ÈÄ¥Í×ÁǤâ¸Æ¤Ó½Ð¤µ¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò¼¨¤¹¡£ */ - - int initial_invocation[2]; - - /***en - Table of code extension elements. The Nth element corresponds - to the Nth charset in $CHARSET_NAMES, which is an argument given - to the mconv_define_coding () function. - - If an element value is 0..3, it specifies a graphic register - number to designate the corresponds charset. In addition, the - charset is initially designated to that graphic register. - - If the value is -4..-1, it specifies a graphic register number - 0..3 respectively to designate the corresponds charset. - Initially, the charset is not designated to any graphic - register. */ - - /***ja - - Éä¹ç³ÈÄ¥Í×ÁǤΥơ¼¥Ö¥ë¡£NÈÖÌܤÎÍ×ÁǤϡ¢$CHARSET_NAMES ¤Î N ÈÖÌÜ - ¤Îʸ»ú¥»¥Ã¥È¤ËÂбþ¤¹¤ë¡£$CHARSET_NAMES ¤Ï´Ø¿ô - mconv_define_coding () ¤Î°ú¿ô¤È¤·¤Æ»È¤ï¤ì¤ë¡£ - - Ãͤ¬ 0..3 ¤À¤Ã¤¿¤é¡¢Âбþ¤¹¤ëʸ»ú¥»¥Ã¥È¤ò G0..G3 ¤Î¤½¤ì¤¾¤ì¤Ë»Ø¼¨ - ¤¹¤ë¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤µ¤é¤Ë¡¢½é´ü¾õÂ֤Ǥ¹¤Ç¤Ë G0..G3 ¤Ë»Ø¼¨¤µ¤ì¤Æ - ¤¤¤ë¡£ - - Ãͤ¬ -4..-1 ¤À¤Ã¤¿¤é¡¢Âбþ¤¹¤ëʸ»ú¥»¥Ã¥È¤ò G0..G3 ¤Î¤½¤ì¤¾¤ì¤Ë»Ø - ¼¨¤¹¤ë¤¬¡¢½é´ü¾õÂ֤ǤϤɤ³¤Ë¤â»Ø¼¨¤µ¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£ */ - - char designations[32]; - - /***en - Bitwise OR of @c enum @c MCodingFlagISO2022 . */ - - /***ja - @c enum @c MCodingFlagISO2022 ¤Î¥Ó¥Ã¥Èñ°Ì¤Ç¤ÎÏÀÍý OR */ - - unsigned flags; - -} MCodingInfoISO2022; -/*=*/ - -/*** @ingroup m17nConv */ -/***en - @brief Structure for extra information about a coding system of - type #MCODING_TYPE_UTF. */ - -/***ja - @brief MCODING_TYPE_UTF ¥¿¥¤¥×¤Î¥³¡¼¥É·Ï¤ÇɬÍפÊÉղþðÊóÍѤι½Â¤ÂÎ - - @latexonly \IPApage{MCodingInfoUTF} @endlatexonly - - @latexonly \IPAlabel{MCodingInfoUTF} @endlatexonly */ - -typedef struct -{ - /***en - Specify bits of a code unit. The value must be 8, 16, or 32. */ - int code_unit_bits; - - /***en - Specify how to handle the heading BOM (byte order mark). The - value must be 0, 1, or 2. The meanings are as follows: - - 0: On decoding, check the first two byte. If they are BOM, - decide endian by them. If not, decide endian by the member @c - endian. On encoding, produce byte sequence according to - @c endian with heading BOM. - - 1: On decoding, do not handle the first two bytes as BOM, and - decide endian by @c endian. On encoding, produce byte sequence - according to @c endian without BOM. - - 2: On decoding, handle the first two bytes as BOM and decide - ending by them. On encoding, produce byte sequence according to - @c endian with heading BOM. - - If is 8, the value has no meaning. */ - - /***ja - ÀèƬ¤Î BOM (¥Ð¥¤¥È¥ª¡¼¥À¡¼¥Þ¡¼¥¯) ¤Î¼è¤ê°·¤¤¤ò»ØÄꤹ¤ë¡£ÃÍ¤Ï 0, - 1, 2 ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Î°ÕÌ£¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£ - - 0: ¥Ç¥³¡¼¥É¤ÎºÝ¤ËºÇ½é¤Î2¥Ð¥¤¥È¤òÄ´¤Ù¤ë¡£¤â¤·¤½¤ì¤¬ BOM ¤Ç¤¢¤ì¤Ð¡¢ - ¥¨¥ó¥Ç¥£¥¢¥ó¤ò¤½¤ì¤ÇȽÄꤹ¤ë¡£¤â¤·ºÇ½é¤Î2¥Ð¥¤¥È¤¬ BOM ¤Ç¤Ê¤±¤ì¤Ð¡¢ - ¥á¥ó¥Ð @c endian ¤Ë½¾¤Ã¤Æ¥¨¥ó¥Ç¥£¥¢¥ó¤ò·èÄꤹ¤ë¡£¥¨¥ó¥³¡¼¥É¤ÎºÝ - ¤Ë¤Ï @c endian ¤Ë½¾¤Ã¤¿¥Ð¥¤¥ÈÎó¤ò BOM ÉÕ¤ÇÀ¸À®¤¹¤ë¡£ - - 1: ¥Ç¥³¡¼¥É¤ÎºÝ¡¢ºÇ½é¤Î2¥Ð¥¤¥È¤ò BOM ¤È¤·¤Æ°·¤ï¤Ê¤¤¡£¥¨¥ó - ¥Ç¥£¥¢¥ó¤Ï @c endian ¤ÇȽÄꤹ¤ë¡£¥¨¥ó¥³¡¼¥É¤ÎºÝ¤Ë¤Ï¡¢BOM - ¤ò½ÐÎϤ»¤º¡¢@c endian ¤Ë±þ¤¸¤¿¥Ð¥¤¥ÈÎó¤òÀ¸À®¤¹¤ë¡£ - - 2: ¥Ç¥³¡¼¥É¤ÎºÝ¤ËºÇ½é¤Î2¥Ð¥¤¥È¤ò BOM¤È¤·¤Æ°·¤¤¡¢¤½¤ì¤Ë½¾¤Ã - ¤Æ¥¨¥ó¥Ç¥£¥¢¥ó¤òȽÄꤹ¤ë¡£¥¨¥ó¥³¡¼¥É¤ÎºÝ¤Ë¤Ï @c endian ¤Ë - ±þ¤¸¤¿¥Ð¥¤¥ÈÎó¤ò BOM ÉÕ¤­¤ÇÀ¸À®¤¹¤ë¡£ */ - int bom; - - /***en - Specify the endian type. The value must be 0 or 1. 0 means - little endian, and 1 means big endian. - - If is 8, the value has no meaning. */ - /***ja - ¥¨¥ó¥Ç¥£¥¢¥ó¤Î¥¿¥¤¥×¤ò»ØÄꤹ¤ë¡£ÃÍ¤Ï 0 ¤« 1 ¤Ç¤¢¤ê¡¢0 ¤Ê¤é¤Ð¥ê¥È - ¥ë¥¨¥ó¥Ç¥£¥¢¥ó¡¢1 ¤Ê¤é¤Ð¥Ó¥Ã¥°¥¨¥ó¥Ç¥£¥¢¥ó¤Ç¤¢¤ë¡£*/ - int endian; -} MCodingInfoUTF; -/*=*/ - -extern MSymbol mconv_define_coding (char *name, MPlist *plist, - int (*resetter) (MConverter *), - int (*decoder) (unsigned char *, int, - MText *, MConverter *), - int (*encoder) (MText *, int, int, - unsigned char *, int, - MConverter *), - void *extra_info); - -extern MSymbol mconv_resolve_coding (MSymbol symbol); - -extern int mconv_list_codings (MSymbol **symbols); - -extern MConverter *mconv_buffer_converter (MSymbol coding, unsigned char *buf, - int n); - -extern MConverter *mconv_stream_converter (MSymbol coding, FILE *fp); - -extern int mconv_reset_converter (MConverter *converter); - -extern void mconv_free_converter (MConverter *converter); - -extern MConverter *mconv_rebind_buffer (MConverter *converter, - unsigned char *buf, int n); - -extern MConverter *mconv_rebind_stream (MConverter *converter, FILE *fp); - -extern MText *mconv_decode (MConverter *converter, MText *mt); - -MText *mconv_decode_buffer (MSymbol name, unsigned char *buf, int n); - -MText *mconv_decode_stream (MSymbol name, FILE *fp); - -extern int mconv_encode (MConverter *converter, MText *mt); - -extern int mconv_encode_range (MConverter *converter, MText *mt, - int from, int to); - -extern int mconv_encode_buffer (MSymbol name, MText *mt, - unsigned char *buf, int n); - -extern int mconv_encode_stream (MSymbol name, MText *mt, FILE *fp); - -extern int mconv_getc (MConverter *converter); - -extern int mconv_ungetc (MConverter *converter, int c); - -extern int mconv_putc (MConverter *converter, int c); - -extern MText *mconv_gets (MConverter *converter, MText *mt); - -/* (S4) Locale related functions corresponding to libc functions */ - -/*** @ingroup m17nShell */ -/***en @defgroup m17nLocale Locale */ -/***ja @defgroup m17nLocale ¥í¥±¡¼¥ë */ -/*=*/ - -/***en - @brief @c struct @c MLocale - - The structure @c MLocale is used to hold information about name, - language, territory, modifier, codeset, and the corresponding - coding system of locales. - - The contents of this structure are implementation dependent. Its - internal structure is concealed from application programs. */ - -/***ja - @brief @c MLocale ¹½Â¤ÂÎ - - @c MLocale ¹½Â¤ÂΤϡ¢¥í¥±¡¼¥ë¤Î̾Á°¡¢¸À¸ì¡¢ÃÏ°è¡¢¥â¥Ç¥£¥Õ¥¡¥¤¥¢¡¢ - ¥³¡¼¥É¥»¥Ã¥È¡¢¤ª¤è¤ÓÂбþ¤¹¤ë¥³¡¼¥É·Ï¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÝ»ý¤¹¤ë¤¿¤á¤ËÍÑ - ¤¤¤é¤ì¤ë¡£ - - ¤³¤Î¹½Â¤ÂΤÎÆâÍƤϼÂÁõ¤Ë°Í¸¤¹¤ë¡£ ÆâÉô¹½Â¤¤Ï¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í - ¥°¥é¥à¤«¤é¤Ï¸«¤¨¤Ê¤¤¡£ */ - -/*** - @seealso - mlocale_get_prop () */ - -typedef struct MLocale MLocale; - -/*=*/ - -extern MSymbol Mlanguage; -extern MSymbol Mterritory; -extern MSymbol Mmodifier; -extern MSymbol Mcodeset; - -extern MLocale *mlocale_set (int category, const char *locale); - -extern MSymbol mlocale_get_prop (MLocale *locale, MSymbol key); - -extern int mtext_ftime (MText *mt, const char *format, const struct tm *tm, - MLocale *locale); - -extern MText *mtext_getenv (const char *name); - -extern int mtext_putenv (MText *mt); - -extern int mtext_coll (MText *mt1, MText *mt2); - -/* - * (9) Miscellaneous functions of libc level (not yet implemented) - */ - -/* -extern int mtext_width (MText *mt, int n); -extern MText *mtext_tolower (MText *mt); -extern MText *mtext_toupper (MText *mt); -*/ - -/* - * (10) Input method - */ - -/*** @ingroup m17nShell */ -/***en @defgroup m17nInputMethod Input Method (basic) */ -/***ja @defgroup m17nInputMethod ÆþÎϥ᥽¥Ã¥É (´ðËÜ) */ -/*=*/ - -/* Struct forward declaration. */ -typedef struct MInputMethod MInputMethod; -typedef struct MInputContext MInputContext; - -/*** @ingroup m17nInputMethod */ - -/***en - @brief Type of input method callback functions. - - This is the type of callback functions called from input method - drivers. #IC is a pointer to an input context, #COMMAND is a name - of callback for which the function is called. */ - -typedef void (*MInputCallbackFunc) (MInputContext *ic, MSymbol command); -/*=*/ - -/***en - @brief Structure of input method driver. - - The type @c MInputDriver is the structure of an input driver that - contains several functions to handle an input method. */ - -/***ja - @brief ÆþÎϥɥ饤¥Ð - - @c MInputDriver ·¿¤Ï¡¢ÆþÎϥ᥽¥Ã¥É¤ò¼è¤ê°·¤¦´Ø¿ô¤ò´Þ¤àÆþÎϥɥ饤¥Ð - ¤Î¹½Â¤ÂΤǤ¢¤ë¡£ */ - -typedef struct MInputDriver -{ - /***en - @brief Open an input method. - - This function opens the input method $IC. It is called from the - function minput_open_im () after all member of $IM but - set. If opening $IM succeeds, it returns 0. Otherwise, it - returns -1. The function can setup $IM->info to keep various - information that is referred by the other driver functions. */ - - /***ja - @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë - - ¤³¤Î´Ø¿ô¤Ï¡¢ÆþÎϥ᥽¥Ã¥É$IM¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£$IM ¤Î°Ê³°¤ÎÁ´ - ¥á¥ó¥Ð¡¼¤¬¥»¥Ã¥È¤µ¤ì¤¿¸å¤Ç¡¢´Ø¿ô minput_open_im () ¤«¤é¸Æ¤Ð¤ì¤ë¡£ - $IM ¤ò¥ª¡¼¥×¥ó¤Ç¤­¤ì¤Ð 0 ¤ò¡¢¤Ç¤­¤Ê¤±¤ì¤Ð -1¤òÊÖ¤¹¡£¤³¤Î´Ø¿ô¤Ï - $IM->info ¤òÀßÄꤷ¤Æ¡¢Â¾¤Î¥É¥é¥¤¥Ð´Ø¿ô¤«¤é»²¾È¤µ¤ì¤ë¾ðÊó¤òÊÝ»ý¤¹ - ¤ë¤³¤È¤¬¤Ç¤­¤ë¡£ - */ - - int (*open_im) (MInputMethod *im); - - /***en - @brief Close an input method. - - This function closes the input method $IM. It is called from - the function minput_close_im (). It frees all memory allocated - for $IM->info (if any) after finishing all the tasks of closing - the input method. But, the other members of $IM should not be - touched. */ - - /***ja - @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë - - ¤³¤Î´Ø¿ô¤Ï´Ø¿ô minput_close_im () ¤«¤é¸Æ¤Ð¤ì¡¢ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼ - ¥º¤¹¤ë¡£¡£ÆþÎϥ᥽¥Ã¥É¤Î¥¯¥í¡¼¥º¤¬¤¹¤Ù¤Æ½ªÎ»¤·¤¿»þÅÀ¤Ç¡¢ - $IM->info ¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥á¥â¥ê¤ò(¤¢¤ì¤Ð)³«Êü¤¹¤ë¡£¤¿¤À¤·¡¢ - $IM ¤Î¾¤Î¥á¥ó¥Ð¤Ë±Æ¶Á¤òÍ¿¤¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */ - - void (*close_im) (MInputMethod *im); - - /***en - @brief Create an input context. - - This function creates the input context $IC. It is called from - the function minput_create_ic () after all members of $IC but - are set. If creating $IC succeeds, it returns 0. - Otherwise, it returns -1. The function can setup $IC->info to - keep various information that is referred by the other driver - functions. */ - - /***ja - @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë - - ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÀ¸À®¤¹¤ë´Ø¿ô¡£¤³¤Î´Ø¿ô¤Ï¡¢$IC ¤Î - °Ê³°¤ÎÁ´¥á¥ó¥Ð¡¼¤¬¥»¥Ã¥È¤µ¤ì¤¿¸å¤Ç¡¢´Ø¿ô minput_create_ic () ¤« - ¤é¸Æ¤Ð¤ì¤ë¡£$IC ¤òÀ¸À®¤Ç¤­¤ì¤Ð 0 ¤ò¡¢¤Ç¤­¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£¤³ - ¤Î´Ø¿ô¤Ï $IC->info ¤òÀßÄꤷ¤Æ¡¢Â¾¤Î¥É¥é¥¤¥Ð´Ø¿ô¤«¤é»²¾È¤µ¤ì¤ë¾ð - Êó¤òÊÝ»ý¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¡£ */ - - - int (*create_ic) (MInputContext *ic); - - /***en - @brief Destroy an input context. - - This function is called from the function minput_destroy_ic () - and destroys the input context $IC. It frees all memory - allocated for $IC->info (if any) after finishing all the tasks - of destroying the input method. But, the other members of $IC - should not be touched. */ - - /***ja - @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë - - ´Ø¿ô minput_destroy_ic () ¤«¤é¸Æ¤Ð¤ì¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇË - ²õ¤¹¤ë¡£ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ÎÇ˲õ¤¬¤¹¤Ù¤Æ½ªÎ»¤·¤¿»þÅÀ¤Ç¡¢$IC->info - ¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥á¥â¥ê¤ò(¤¢¤ì¤Ð)³«Êü¤¹¤ë¡£¤¿¤À¤·¡¢$IC ¤Î¾¤Î - ¥á¥ó¥Ð¤Ë±Æ¶Á¤òÍ¿¤¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */ - - void (*destroy_ic) (MInputContext *ic); - - /***en - @brief Filter an input key. - - This function is called from the function minput_filter () and - filters an input key. $KEY and $ARG are the same as what given - to minput_filter (). - - The task of the function is to handle $KEY, update the internal - state of $IC. If $KEY is absorbed by the input method and no - text is produced, it returns 1. Otherwise, it returns 0. - - It may update $IC->status, $IC->preedit, $IC->cursor_pos, - $IC->ncandidates, $IC->candidates, and $IC->produced if that is - necessary for the member . - - The meaning of $ARG depends on the input driver. See the - documentation of @c minput_default_driver and @c - minput_gui_driver for instance. */ - - /***ja - @brief ÆþÎÏ¥¤¥Ù¥ó¥È¤¢¤ë¤¤¤ÏÆþÎÏ¥­¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë - - ´Ø¿ô minput_filter () ¤«¤é¸Æ¤Ð¤ì¡¢ÆþÎÏ¥­¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë¡£°ú¿ô - $KEY, $ARG ¤Ï´Ø¿ô minput_filter () ¤Î¤â¤Î¤ÈƱ¤¸¡£ - - ¤³¤Î´Ø¿ô¤Ï $KEY ¤ò½èÍý¤·¡¢$IC ¤ÎÆâÉô¾õÂÖ¤ò¥¢¥Ã¥×¥Ç¡¼¥È¤¹¤ë¡£ - $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤ËµÛ¼ý¤µ¤ì¤Æ¥Æ¥­¥¹¥È¤¬À¸À®¤µ¤ì¤Ê¤«¤Ã¤¿¾ì¹ç¤Ë - ¤Ï¡¢ 1 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤¹¡£ - - ¥á¥ó¥Ð ¤ËɬÍפǤ¢¤ì¤Ð¡¢$IC->status, $IC->preedit, - $IC->cursor_pos, $IC->ncandidates, $IC->candidates, - $IC->produced ¤ò¥¢¥Ã¥×¥Ç¡¼¥È¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¡£ - - $ARG ¤Î°ÕÌ£¤ÏÆþÎϥɥ饤¥Ð¤Ë°Í¸¤¹¤ë¡£Îã¤Ï @c - minput_default_driver ¤Þ¤¿¤Ï @c minput_gui_driver ¤Î¥É¥­¥å¥á¥ó¥È - ¤ò»²¾È¤Î¤³¤È¡£ */ - - int (*filter) (MInputContext *ic, MSymbol key, void *arg); - - /***en - @brief Lookup a produced text in an input context - - It is called from the function minput_lookup () and looks up a - produced text in the input context $IC. This function - concatenate a text produced by the input key $KEY (if any) to - M-text $MT. If $KEY was correctly handled by the input method - of $IC, it returns 0. Otherwise, it returns 1. - - The meaning of $ARG depends on the input driver. See the - documentation of @c minput_default_driver and @c - minput_gui_driver for instance. */ - - /***ja - @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ÇÀ¸À®¤µ¤ì¤ë¥Æ¥­¥¹¥È¤Î³ÍÆÀ - - ´Ø¿ô minput_lookup () ¤«¤é¸Æ¤Ð¤ì¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ÇÀ¸À®¤µ - ¤ì¤ë¥Æ¥­¥¹¥È¤ò¸¡º÷¤¹¤ë¡£ÆþÎÏ¥­¡¼ $KEY ¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤ë¥Æ¥­¥¹¥È - ¤¬¤¢¤ì¤Ð¡¢$IC->produced ¤ËÀßÄꤹ¤ë¡£ $KEY ¤¬ÆþÎϥ᥽¥Ã¥É $IC ¤Ë - ¤è¤Ã¤ÆÀµ¤·¤¯½èÍý¤µ¤ì¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 1 ¤òÊÖ¤¹¡£ - - $ARG ¤Î°ÕÌ£¤ÏÆþÎϥɥ饤¥Ð¤Ë°Í¸¤¹¤ë¡£Îã¤Ï @c - minput_default_driver ¤Þ¤¿¤Ï @c minput_gui_driver ¤Î¥É¥­¥å¥á¥ó¥È - ¤ò»²¾È¤Î¤³¤È¡£ */ - - int (*lookup) (MInputContext *ic, MSymbol key, void *arg, MText *mt); - - /***en - @brief List of callback functions. - - List of callback functions. Keys are one of - #Minput_preedit_start, #Minput_preedit_draw, - #Minput_preedit_done, #Minput_status_start, #Minput_status_draw, - #Minput_status_done, #Minput_candidates_start, - #Minput_candidates_draw, #Minput_candidates_done, - #Minput_set_spot, and #Minput_toggle. Values are functions of - type #MInputCallbackFunc. */ - MPlist *callback_list; - -} MInputDriver; -/*=*/ - -extern MInputDriver minput_default_driver; - -extern MSymbol Minput_driver; - -extern MInputDriver *minput_driver; - -/** Symbols for callback commands. */ -extern MSymbol Minput_preedit_start; -extern MSymbol Minput_preedit_draw; -extern MSymbol Minput_preedit_done; -extern MSymbol Minput_status_start; -extern MSymbol Minput_status_draw; -extern MSymbol Minput_status_done; -extern MSymbol Minput_candidates_start; -extern MSymbol Minput_candidates_draw; -extern MSymbol Minput_candidates_done; -extern MSymbol Minput_set_spot; -extern MSymbol Minput_toggle; - -/***en - @brief Structure of input method. - - The type @c MInputMethod is the structure of input method - objects. */ -/***ja - @brief ÆþÎϥ᥽¥Ã¥ÉÍѹ½Â¤ÂÎ - - @c MInputMethod ·¿¤Ï¡¢ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥ÈÍѤι½Â¤ÂΤǤ¢¤ë¡£ */ - -struct MInputMethod -{ - /***en Which language this input method is for. The value is @c - Mnil if the input method is foreign. */ - /***ja ¤É¤Î¸À¸ìÍѤÎÆþÎϥ᥽¥Ã¥É¤«¡£ÆþÎϥ᥽¥Ã¥É¤¬³°Éô¤Î¤â¤Î¤Ç¤¢¤ë¾ì - ¹ç¤Ë¤ÏÃͤȤ·¤Æ @c ¤ò»ý¤Ä¡£ */ - MSymbol language; - - /***en Name of the input method. If the input method is foreign, it - must has a property of key @c Minput_driver and the value must be a - pointer to a proper input driver. */ - /***ja ÆþÎϥ᥽¥Ã¥É¤Î̾Á°¡£³°Éô¥á¥½¥Ã¥É¤Ç¤¢¤ë¾ì¹ç¤Ë¤Ï¡¢@c - Minput_driver ¤ò¥­¡¼¤È¤¹¤ë¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Á¡¢¤½¤ÎÃͤÏŬÀÚ¤ÊÆþÎ촃 - ¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/ - MSymbol name; - - /***en Input driver of the input method. */ - /***ja ¤½¤ÎÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥɥ饤¥Ð */ - MInputDriver driver; - - /***en The argument given to minput_open_im (). */ - /***ja minput_open_im () ¤ËÍ¿¤¨¤é¤ì¤ë°ú¿ô */ - void *arg; - - /***en Pointer to extra information that .open_im () - setups. */ - /***ja .open_im () ¤¬ÀßÄꤹ¤ëÄɲþðÊó¤Ø¤Î¥Ý¥¤¥ó¥¿ */ - void *info; -}; - -/*=*/ - -/***en - @brief Structure of input context. - - The type @c MInputContext is the structure of input context - objects. */ - -/***ja - @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÍѹ½Â¤ÂÎ - - @c MInputContext ·¿¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥ÈÍѤι½Â¤ÂΤǤ¢ - ¤ë¡£ */ - -struct MInputContext -{ - /***en Backward pointer to the input method. It is set up be the - function minput_create_ic (). */ - /***ja ÆþÎϥ᥽¥Ã¥É¤Ø¤ÎµÕ¥Ý¥¤¥ó¥¿¡£´Ø¿ô minput_create_ic () ¤Ë¤è¤Ã¤Æ - ÀßÄꤵ¤ì¤ë¡£ */ - MInputMethod *im; - - /***en M-text produced by the input method. It is set up by the - function minput_lookup () . */ - /***ja ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤ë M-text¡£´Ø¿ô minput_lookup () - ¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë¡£ */ - MText *produced; - - /***en Argument given to the function minput_create_im (). */ - /***ja ´Ø¿ô minput_create_ic () ¤ËÅϤµ¤ì¤ë°ú¿ô */ - void *arg; - - /***en Flag telling whether the input context is currently active or - inactive. The value is set to 1 (active) when the input context - is created. It can be toggled by the function minput_toggle - (). */ - /***ja ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬¥¢¥¯¥Æ¥£¥Ö¤«¤É¤¦¤«¤ò¼¨¤¹¥Õ¥é¥°¡£ÆþÎÏ¥³¥ó¥Æ - ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿»þÅÀ¤Ç¤ÏÃÍ¤Ï 1 ¡Ê¥¢¥¯¥Æ¥£¥Ö¡Ë¤Ç¤¢¤ê¡¢´Ø¿ô - minput_toggle () ¤Ë¤è¤Ã¤Æ¥È¥°¥ë¤Ç¤­¤ë¡£ */ - int active; - - - /***en Spot location and size of the input context. */ - /***ja ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤Î°ÌÃÖ¤ÈÂ礭¤µ */ - struct { - /***en X and Y coordinate of the spot. */ - /***ja ¥¹¥Ý¥Ã¥È¤Î X, Y ºÂɸ */ - int x, y; - /***en Ascent and descent pixels of the line of the spot. */ - /***ja ¥¹¥Ý¥Ã¥È¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤Î¥Ô¥¯¥»¥ë¿ô */ - int ascent, descent; - - /***en Font size for preedit text in 1/10 point. */ - int fontsize; - - /***en M-text at the spot, or NULL. */ - MText *mt; - /***en Character position in at the spot. */ - int pos; - } spot; - - /***en The usage of the following members depends on the input - driver. The descriptions below are for the input driver of an - internal input method. They are set by the function - ->driver.filter (). */ - /***ja °Ê²¼¤Î¥á¥ó¥Ð¤Î»ÈÍÑË¡¤ÏÆþÎϥɥ饤¥Ð¤Ë¤è¤Ã¤Æ°Û¤Ê¤ë¡£°Ê²¼¤ÎÀâÌÀ - ¤Ï¡¢ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥɥ饤¥Ð¤ËÂФ¹¤ë¤â¤Î¤Ç¤¢¤ë¡£ */ - - /***en Pointer to extra information that ->driver.create_ic () - setups. It is used to record the internal state of the input - context. */ - /***ja ->driver.create_ic () ¤¬ÀßÄꤹ¤ëÄɲþðÊó¤Ø¤Î¥Ý¥¤¥ó¥¿¡£Æþ - ÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ÎÆâÉô¾õÂÖ¤òµ­Ï¿¤¹¤ë¤¿¤á¤ËÍѤ¤¤é¤ì¤ë¡£ */ - void *info; - - /***en M-text describing the current status of the input - context. */ - /***ja ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¸½ºß¤Î¾õ¶·¤òɽ¤¹ M-text */ - MText *status; - - /***en The function ->driver.filter () sets the value to 1 when - it changes . */ - int status_changed; - - /***en M-text containing the current preedit text. The function - ->driver.filter () sets the value. */ - /***ja ¸½ºß¤Î preedit ¥Æ¥­¥¹¥È¤ò´Þ¤à M-text */ - MText *preedit; - - /***en The function ->driver.filter () sets the value to 1 when - it changes . */ - int preedit_changed; - - /***en Cursor position of . */ - /***ja ¤Î¥«¡¼¥½¥ë°ÌÃÖ */ - int cursor_pos; - - int cursor_pos_changed; - - /***en Array of the current candidate texts. */ - /***ja ¸½ºß¤Î¥Æ¥­¥¹¥È¸õÊä¤Î¥°¥ë¡¼¥×¤Î¥ê¥¹¥È */ - MPlist *candidate_list; - int candidate_index; - int candidate_from, candidate_to; - int candidate_show; - - /***en The function ->driver.filter () sets the value to 1 when - it changes one of the above members. */ - int candidates_changed; - - MPlist *plist; -}; - -/*=*/ - -extern MInputMethod *minput_open_im (MSymbol language, MSymbol name, - void *arg); - -/*=*/ - -extern void minput_close_im (MInputMethod *im); - -extern MInputContext *minput_create_ic (MInputMethod *im, void *arg); - -extern void minput_destroy_ic (MInputContext *ic); - -extern int minput_filter (MInputContext *ic, MSymbol key, void *arg); - -extern int minput_lookup (MInputContext *ic, MSymbol key, void *arg, - MText *mt); - -extern void minput_set_spot (MInputContext *ic, int x, int y, - int ascent, int descent, int fontsize, - MText *mt, int pos); - -extern void minput_toggle (MInputContext *ic); - -extern MSymbol minput_char_to_key (int c); - -/*=*/ - -extern MInputMethod *mdebug_dump_im (MInputMethod *im, int indent); - -#ifdef __cplusplus -} -#endif - -#endif /* _M17N_H_ */ - -/* - Local Variables: - coding: euc-japan - End: -*/ diff --git a/src/mlocale.h b/src/mlocale.h deleted file mode 100644 index 306dfe9..0000000 --- a/src/mlocale.h +++ /dev/null @@ -1,30 +0,0 @@ -/* mlocale.c -- header file for the locale module. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -#ifndef _M17N_LOCAL_H_ -#define _M17N_LOCAL_H_ - -/** The current locales of each category. */ -extern MLocale *mlocale__collate, *mlocale__ctype; -extern MLocale *mlocale__messages, *mlocale__time; - -#endif /* _M17N_LOCAL_H_ */ diff --git a/src/mtext.c b/src/mtext.c deleted file mode 100644 index d052cfe..0000000 --- a/src/mtext.c +++ /dev/null @@ -1,2491 +0,0 @@ -/* mtext.c -- M-text module. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -/***en - @addtogroup m17nMtext - @brief M-text objects and API for them. - - In the m17n library, text is represented as an object called @e - M-text rather than as a C-string (char * or unsigned - char *). An M-text is a sequence of characters whose length - is equals to or more than 0, and can be coined from various - character sources, e.g. C-strings, files, character codes, etc. - - M-texts are more useful than C-strings in the following points. - - @li M-texts can handle mixture of characters of various scripts, - including all Unicode characters and more. This is an - indispensable facility when handling multilingual text. - - @li Each character in an M-text can have properties called @e text - @e properties. Text properties store various kinds of information - attached to parts of an M-text to provide application programs - with a unified view of those information. As rich information can - be stored in M-texts in the form of text properties, functions in - application programs can be simple. - - In addition, the library provides many functions to manipulate an - M-text just the same way as a C-string. */ - -/***ja - @addtogroup m17nMtext - - @brief M-text ¥ª¥Ö¥¸¥§¥¯¥È¤È¤½¤ì¤Ë´Ø¤¹¤ë API - - m17n ¥é¥¤¥Ö¥é¥ê¤ÏÄ̾ï¤Î C-string¡Êchar * ¤ä unsigned - char *¡Ë¤Ç¤Ï¤Ê¤¯ M-text ¤È¸Æ¤Ö¥ª¥Ö¥¸¥§¥¯¥È¤Ç¥Æ¥­¥¹¥È¤òɽ¸½¤¹ - ¤ë¡£M-text ¤ÏŤµ£°°Ê¾å¤Îʸ»ú¤ÎÎ󤫤é¤Ê¤ê¡¢¼ï¡¹¤Îʸ»ú¥½¡¼¥¹¡ÊÎ㤨 - ¤Ð C-string¡¢¥Õ¥¡¥¤¥ë¡¢Ê¸»ú¥³¡¼¥ÉÅù¡Ë¤«¤éºîÀ®¤Ç¤­¤ë¡£ - - M-text ¤Ë¤Ï¡¢C-string ¤Ë¤Ê¤¤°Ê²¼¤ÎÆÃħ¤¬¤¢¤ë¡£ - - @li M-text ¤ÏÈó¾ï¤Ë¿¤¯¤Î¼ïÎà¤Îʸ»ú¤ò¡¢Æ±»þ¤Ë¡¢º®ºß¤µ¤»¤Æ¡¢Æ±Åù¤Ë - °·¤¦¤³¤È¤¬¤Ç¤­¤ë¡£Unicode ¤ÎÁ´¤Æ¤Îʸ»ú¤Ï¤â¤Á¤í¤ó¡¢¤è¤ê¿¤¯¤Îʸ»ú¤Þ - ¤Ç°·¤¨¤ë¡£¤³¤ì¤Ï¿¸À¸ì¥Æ¥­¥¹¥È¤ò°·¤¦¾å¤Ç¤Ïɬ¿Ü¤Îµ¡Ç½¤Ç¤¢¤ë¡£ - - @li M-text Æâ¤Î³Æʸ»ú¤Ï¡¢@e ¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£ ¤È¸Æ¤Ð¤ì¤ë¥×¥í¥Ñ¥Æ¥£ - ¤ò»ý¤Ä¤³¤È¤¬¤Ç¤­¤ë¡£¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Ë¤è¤Ã¤Æ¡¢¥Æ¥­¥¹¥È¤Î³ÆÉô°Ì¤Ë - ´Ø¤¹¤ëÍÍ¡¹¤Ê¾ðÊó¤ò M-text Æâ¤ËÊÝ»ý¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¡£¤½¤Î¤¿¤á¡¢¤½¤ì - ¤é¤Î¾ðÊó¤ò¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥àÆâ¤ÇÅý°ìŪ¤Ë°·¤¦¤³¤È¤¬¤Ç¤­¤ë¡£ - ¤Þ¤¿¡¢M-text ¼«ÂΤ¬Ë­É٤ʾðÊó¤ò»ý¤Ä¤¿¤á¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é - ¥àÃæ¤Î³Æ´Ø¿ô¤ò´ÊÁDz½¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¡£ - - ¤µ¤é¤Ë¡¢m17n ¥é¥¤¥Ö¥é¥ê¤Ï C-string ¤òÁàºî¤¹¤ë¤¿¤á¤ËÄ󶡤µ¤ì¤ë¼ï¡¹¤Î - ´Ø¿ô¤ÈƱÅù¤â¤Î¤ò M-text ¤òÁàºî¤¹¤ë¤¿¤á¤ËÄ󶡤¹¤ë¡£ */ - -/*=*/ - -#if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE) -/*** @addtogroup m17nInternal - @{ */ - -#include -#include -#include -#include -#include - -#include "m17n.h" -#include "m17n-misc.h" -#include "internal.h" -#include "textprop.h" -#include "character.h" -#include "mtext.h" -#include "plist.h" - -static M17NObjectArray mtext_table; - -static MSymbol M_charbag; - -#ifdef WORDS_BIGENDIAN -static enum MTextFormat default_utf_16 = MTEXT_FORMAT_UTF_16BE; -static enum MTextFormat default_utf_32 = MTEXT_FORMAT_UTF_32BE; -#else -static enum MTextFormat default_utf_16 = MTEXT_FORMAT_UTF_16LE; -static enum MTextFormat default_utf_32 = MTEXT_FORMAT_UTF_32LE; -#endif - -/** Increment character position CHAR_POS and byte position BYTE_POS - so that they point to the next character in M-text MT. No range - check for CHAR_POS and BYTE_POS. */ - -#define INC_POSITION(mt, char_pos, byte_pos) \ - do { \ - int c; \ - \ - if ((mt)->format == MTEXT_FORMAT_UTF_8) \ - { \ - c = (mt)->data[(byte_pos)]; \ - (byte_pos) += CHAR_UNITS_BY_HEAD_UTF8 (c); \ - } \ - else \ - { \ - c = ((unsigned short *) ((mt)->data))[(byte_pos)]; \ - \ - if ((mt)->format != default_utf_16) \ - c = SWAP_16 (c); \ - (byte_pos) += (c < 0xD800 || c >= 0xE000) ? 1 : 2; \ - } \ - (char_pos)++; \ - } while (0) - - -/** Decrement character position CHAR_POS and byte position BYTE_POS - so that they point to the previous character in M-text MT. No - range check for CHAR_POS and BYTE_POS. */ - -#define DEC_POSITION(mt, char_pos, byte_pos) \ - do { \ - if ((mt)->format == MTEXT_FORMAT_UTF_8) \ - { \ - unsigned char *p1 = (mt)->data + (byte_pos); \ - unsigned char *p0 = p1 - 1; \ - \ - while (! CHAR_HEAD_P (p0)) p0--; \ - (byte_pos) -= (p1 - p0); \ - } \ - else \ - { \ - int c = ((unsigned short *) ((mt)->data))[(byte_pos) - 1]; \ - \ - if ((mt)->format != default_utf_16) \ - c = SWAP_16 (c); \ - (byte_pos) -= (c < 0xD800 || c >= 0xE000) ? 1 : 2; \ - } \ - (char_pos)--; \ - } while (0) - - -static int -compare (MText *mt1, int from1, int to1, MText *mt2, int from2, int to2) -{ - if (mt1->format == mt2->format - && (mt1->format < MTEXT_FORMAT_UTF_8)) - { - unsigned char *p1, *pend1, *p2, *pend2; - - p1 = mt1->data + mtext__char_to_byte (mt1, from1); - pend1 = mt1->data + mtext__char_to_byte (mt1, to1); - - p2 = mt2->data + mtext__char_to_byte (mt2, from2); - pend2 = mt2->data + mtext__char_to_byte (mt2, to2); - - for (; p1 < pend1 && p2 < pend2; p1++, p2++) - if (*p1 != *p2) - return (*p1 > *p2 ? 1 : -1); - return (p2 == pend2 ? (p1 < pend1) : -1); - } - for (; from1 < to1 && from2 < to2; from1++, from2++) - { - int c1 = mtext_ref_char (mt1, from1); - int c2 = mtext_ref_char (mt2, from2); - - if (c1 != c2) - return (c1 > c2 ? 1 : -1); - } - return (from2 == to2 ? (from1 < to1) : -1); -} - -static MText * -copy (MText *mt1, int pos, MText *mt2, int from, int to) -{ - int pos_byte = POS_CHAR_TO_BYTE (mt1, pos); - int nbytes; - struct MTextPlist *plist; - unsigned char *p; - - if (mt2->format <= MTEXT_FORMAT_UTF_8) - { - int from_byte = POS_CHAR_TO_BYTE (mt2, from); - - p = mt2->data + from_byte; - nbytes = POS_CHAR_TO_BYTE (mt2, to) - from_byte; - } - else - { - unsigned char *p1; - int pos1; - - p = p1 = alloca (MAX_UNICODE_CHAR_BYTES * (to - from)); - for (pos1 = from; pos1 < to; pos1++) - { - int c = mtext_ref_char (mt2, pos1); - p1 += CHAR_STRING (c, p1); - } - nbytes = p1 - p; - } - - if (mt1->cache_char_pos > pos) - { - mt1->cache_char_pos = pos; - mt1->cache_byte_pos = pos_byte; - } - - if (pos_byte + nbytes >= mt1->allocated) - { - mt1->allocated = pos_byte + nbytes + 1; - MTABLE_REALLOC (mt1->data, mt1->allocated, MERROR_MTEXT); - } - memcpy (mt1->data + pos_byte, p, nbytes); - mt1->nbytes = pos_byte + nbytes; - mt1->data[mt1->nbytes] = 0; - - plist = mtext__copy_plist (mt2->plist, from, to, mt1, pos); - if (pos == 0) - { - if (mt1->plist) - mtext__free_plist (mt1); - mt1->plist = plist; - } - else - { - if (pos < mt1->nchars) - mtext__adjust_plist_for_delete (mt1, pos, mt1->nchars - pos); - if (from < to) - mtext__adjust_plist_for_insert (mt1, pos, to - from, plist); - } - - mt1->nchars = pos + (to - from); - if (mt1->nchars < mt1->nbytes) - mt1->format = MTEXT_FORMAT_UTF_8; - return mt1; -} - - -static MCharTable * -get_charbag (MText *mt) -{ - MTextProperty *prop = mtext_get_property (mt, 0, M_charbag); - MCharTable *table; - int i; - - if (prop) - { - if (prop->end == mt->nchars) - return ((MCharTable *) prop->val); - mtext_detach_property (prop); - } - - table = mchartable (Msymbol, (void *) 0); - for (i = mt->nchars - 1; i >= 0; i--) - mchartable_set (table, mtext_ref_char (mt, i), Mt); - prop = mtext_property (M_charbag, table, MTEXTPROP_VOLATILE_WEAK); - mtext_attach_property (mt, 0, mtext_nchars (mt), prop); - M17N_OBJECT_UNREF (prop); - return table; -} - - -/* span () : Number of consecutive chars starting at POS in MT1 that - are included (if NOT is Mnil) or not included (if NOT is Mt) in - MT2. */ - -static int -span (MText *mt1, MText *mt2, int pos, MSymbol not) -{ - int nchars = mtext_nchars (mt1); - MCharTable *table = get_charbag (mt2); - int i; - - for (i = pos; i < nchars; i++) - if ((MSymbol) mchartable_lookup (table, mtext_ref_char (mt1, i)) == not) - break; - return (i - pos); -} - - -static int -count_utf_8_chars (void *data, int nitems) -{ - unsigned char *p = (unsigned char *) data; - unsigned char *pend = p + nitems; - int nchars = 0; - - while (p < pend) - { - int i, n; - - for (; p < pend && *p < 128; nchars++, p++); - if (p == pend) - return nchars; - if (! CHAR_HEAD_P_UTF8 (p)) - return -1; - n = CHAR_UNITS_BY_HEAD_UTF8 (*p); - if (p + n > pend) - return -1; - for (i = 1; i < n; i++) - if (CHAR_HEAD_P_UTF8 (p + i)) - return -1; - p += n; - nchars++; - } - return nchars; -} - -static int -count_utf_16_chars (void *data, int nitems, int swap) -{ - unsigned short *p = (unsigned short *) data; - unsigned short *pend = p + nitems; - int nchars = 0; - - while (p < pend) - { - unsigned b; - - for (; p < pend; nchars++, p++) - { - b = swap ? *p & 0xFF : *p >> 8; - - if (b >= 0xD8 && b < 0xE0) - { - if (b >= 0xDC) - return -1; - break; - } - } - if (p == pend) - break; - if (p + 1 == pend) - return -1; - p++; - b = swap ? *p & 0xFF : *p >> 8; - if (b < 0xDC || b >= 0xE0) - return -1; - nchars++; - p++; - } - - return nchars; -} - - -static int -find_char_forward (MText *mt, int from, int to, int c) -{ - int from_byte = POS_CHAR_TO_BYTE (mt, from); - - if (mt->format <= MTEXT_FORMAT_UTF_8) - { - unsigned char *p = mt->data + from_byte; - - while (from < to && STRING_CHAR_ADVANCE_UTF8 (p) != c) from++; - } - else if (mt->format <= MTEXT_FORMAT_UTF_16LE) - { - unsigned short *p = (unsigned short *) (mt->data) + from_byte; - - if (mt->format == default_utf_16) - { - unsigned short *p = (unsigned short *) (mt->data) + from_byte; - - while (from < to && STRING_CHAR_ADVANCE_UTF16 (p) != c) from++; - } - else if (c < 0x10000) - { - c = SWAP_16 (c); - while (from < to && *p != c) - { - from++; - p += ((*p & 0xFF) < 0xD8 || (*p & 0xFF) >= 0xE0) ? 1 : 2; - } - } - else if (c < 0x110000) - { - int c1 = (c >> 10) + 0xD800; - int c2 = (c & 0x3FF) + 0xDC00; - - c1 = SWAP_16 (c1); - c2 = SWAP_16 (c2); - while (from < to && (*p != c1 || p[1] != c2)) - { - from++; - p += ((*p & 0xFF) < 0xD8 || (*p & 0xFF) >= 0xE0) ? 1 : 2; - } - } - } - else if (c < 0x110000) - { - unsigned *p = (unsigned *) (mt->data) + from_byte; - unsigned c1 = c; - - if (mt->format != default_utf_32) - c1 = SWAP_32 (c1); - while (from < to && *p++ != c1) from++; - } - - return (from < to ? from : -1); -} - - -static int -find_char_backward (MText *mt, int from, int to, int c) -{ - int to_byte = POS_CHAR_TO_BYTE (mt, to); - - if (mt->format <= MTEXT_FORMAT_UTF_8) - { - unsigned char *p = mt->data + to_byte; - - while (from < to) - { - for (p--; ! CHAR_HEAD_P (p); p--); - if (c == STRING_CHAR (p)) - break; - to--; - } - } - else if (mt->format <= MTEXT_FORMAT_UTF_16LE) - { - unsigned short *p = (unsigned short *) (mt->data) + to_byte; - - if (mt->format == default_utf_16) - { - while (from < to) - { - p--; - if (*p >= 0xDC00 && *p < 0xE000) - p--; - if (c == STRING_CHAR_UTF16 (p)) - break; - to--; - } - } - else if (c < 0x10000) - { - c = SWAP_16 (c); - while (from < to && p[-1] != c) - { - to--; - p -= ((p[-1] & 0xFF) < 0xD8 || (p[-1] & 0xFF) >= 0xE0) ? 1 : 2; - } - } - else if (c < 0x110000) - { - int c1 = (c >> 10) + 0xD800; - int c2 = (c & 0x3FF) + 0xDC00; - - c1 = SWAP_32 (c1); - c2 = SWAP_32 (c2); - while (from < to && (p[-1] != c2 || p[-2] != c1)) - { - to--; - p -= ((p[-1] & 0xFF) < 0xD8 || (p[-1] & 0xFF) >= 0xE0) ? 1 : 2; - } - } - } - else if (c < 0x110000) - { - unsigned *p = (unsigned *) (mt->data) + to_byte; - unsigned c1 = c; - - if (mt->format != default_utf_32) - c1 = SWAP_32 (c1); - while (from < to && p[-1] != c1) to--, p--; - } - - return (from < to ? to - 1 : -1); -} - - -static void -free_mtext (void *object) -{ - MText *mt = (MText *) object; - - if (mt->plist) - mtext__free_plist (mt); - if (mt->data && mt->allocated >= 0) - free (mt->data); - M17N_OBJECT_UNREGISTER (mtext_table, mt); - free (object); -} - -/** Structure for an iterator used in case-fold comparison. */ - -struct casecmp_iterator { - MText *mt; - int pos; - MText *folded; - unsigned char *foldedp; - int folded_len; -}; - -static int -next_char_from_it (struct casecmp_iterator *it) -{ - int c, c1; - - if (it->folded) - { - c = STRING_CHAR_AND_BYTES (it->foldedp, it->folded_len); - return c; - } - - c = mtext_ref_char (it->mt, it->pos); - c1 = (int) mchar_get_prop (c, Msimple_case_folding); - if (c1 == 0xFFFF) - { - it->folded - = (MText *) mchar_get_prop (c, Mcomplicated_case_folding); - it->foldedp = it->folded->data; - c = STRING_CHAR_AND_BYTES (it->foldedp, it->folded_len); - return c; - } - - if (c1 >= 0) - c = c1; - return c; -} - -static void -advance_it (struct casecmp_iterator *it) -{ - if (it->folded) - { - it->foldedp += it->folded_len; - if (it->foldedp == it->folded->data + it->folded->nbytes) - it->folded = NULL; - } - if (! it->folded) - { - it->pos++; - } -} - -static int -case_compare (MText *mt1, int from1, int to1, MText *mt2, int from2, int to2) -{ - struct casecmp_iterator it1, it2; - - it1.mt = mt1, it1.pos = from1, it1.folded = NULL; - it2.mt = mt2, it2.pos = from2, it2.folded = NULL; - - while (it1.pos < to1 && it2.pos < to2) - { - int c1 = next_char_from_it (&it1); - int c2 = next_char_from_it (&it2); - - if (c1 != c2) - return (c1 > c2 ? 1 : -1); - advance_it (&it1); - advance_it (&it2); - } - return (it2.pos == to2 ? (it1.pos < to1) : -1); -} - - -/* Internal API */ - -int -mtext__init () -{ - M_charbag = msymbol_as_managing_key (" charbag"); - mtext_table.count = 0; - return 0; -} - - -void -mtext__fini (void) -{ - mdebug__report_object ("M-text", &mtext_table); -} - - -int -mtext__char_to_byte (MText *mt, int pos) -{ - int char_pos, byte_pos; - int forward; - - if (pos < mt->cache_char_pos) - { - if (mt->cache_char_pos == mt->cache_byte_pos) - return pos; - if (pos < mt->cache_char_pos - pos) - { - char_pos = byte_pos = 0; - forward = 1; - } - else - { - char_pos = mt->cache_char_pos; - byte_pos = mt->cache_byte_pos; - forward = 0; - } - } - else - { - if (mt->nchars - mt->cache_char_pos == mt->nbytes - mt->cache_byte_pos) - return (mt->cache_byte_pos + (pos - mt->cache_char_pos)); - if (pos - mt->cache_char_pos < mt->nchars - pos) - { - char_pos = mt->cache_char_pos; - byte_pos = mt->cache_byte_pos; - forward = 1; - } - else - { - char_pos = mt->nchars; - byte_pos = mt->nbytes; - forward = 0; - } - } - if (forward) - while (char_pos < pos) - INC_POSITION (mt, char_pos, byte_pos); - else - while (char_pos > pos) - DEC_POSITION (mt, char_pos, byte_pos); - mt->cache_char_pos = char_pos; - mt->cache_byte_pos = byte_pos; - return byte_pos; -} - -/* mtext__byte_to_char () */ - -int -mtext__byte_to_char (MText *mt, int pos_byte) -{ - int char_pos, byte_pos; - int forward; - - if (pos_byte < mt->cache_byte_pos) - { - if (mt->cache_char_pos == mt->cache_byte_pos) - return pos_byte; - if (pos_byte < mt->cache_byte_pos - pos_byte) - { - char_pos = byte_pos = 0; - forward = 1; - } - else - { - char_pos = mt->cache_char_pos; - byte_pos = mt->cache_byte_pos; - forward = 0; - } - } - else - { - if (mt->nchars - mt->cache_char_pos == mt->nbytes - mt->cache_byte_pos) - return (mt->cache_char_pos + (pos_byte - mt->cache_byte_pos)); - if (pos_byte - mt->cache_byte_pos < mt->nbytes - pos_byte) - { - char_pos = mt->cache_char_pos; - byte_pos = mt->cache_byte_pos; - forward = 1; - } - else - { - char_pos = mt->nchars; - byte_pos = mt->nbytes; - forward = 0; - } - } - if (forward) - while (byte_pos < pos_byte) - INC_POSITION (mt, char_pos, byte_pos); - else - while (byte_pos > pos_byte) - DEC_POSITION (mt, char_pos, byte_pos); - mt->cache_char_pos = char_pos; - mt->cache_byte_pos = byte_pos; - return char_pos; -} - -/* Estimated extra bytes that malloc will use for its own purpose on - each memory allocation. */ -#define MALLOC_OVERHEAD 4 -#define MALLOC_MININUM_BYTES 12 - -void -mtext__enlarge (MText *mt, int nbytes) -{ - nbytes += MAX_UTF8_CHAR_BYTES; - if (mt->allocated >= nbytes) - return; - if (nbytes < MALLOC_MININUM_BYTES) - nbytes = MALLOC_MININUM_BYTES; - while (mt->allocated < nbytes) - mt->allocated = mt->allocated * 2 + MALLOC_OVERHEAD; - MTABLE_REALLOC (mt->data, mt->allocated, MERROR_MTEXT); -} - -int -mtext__takein (MText *mt, int nchars, int nbytes) -{ - if (mt->plist) - mtext__adjust_plist_for_insert (mt, mt->nchars, nchars, NULL); - mt->nchars += nchars; - mt->nbytes += nbytes; - mt->data[mt->nbytes] = 0; - return 0; -} - - -int -mtext__cat_data (MText *mt, unsigned char *p, int nbytes, - enum MTextFormat format) -{ - int nchars = -1; - - if (mt->format > MTEXT_FORMAT_UTF_8) - MERROR (MERROR_MTEXT, -1); - if (format == MTEXT_FORMAT_US_ASCII) - nchars = nbytes; - else if (format == MTEXT_FORMAT_UTF_8) - nchars = count_utf_8_chars (p, nbytes); - if (nchars < 0) - MERROR (MERROR_MTEXT, -1); - mtext__enlarge (mt, mtext_nbytes (mt) + nbytes + 1); - memcpy (MTEXT_DATA (mt) + mtext_nbytes (mt), p, nbytes); - mtext__takein (mt, nchars, nbytes); - return nchars; -} - -MText * -mtext__from_data (void *data, int nitems, enum MTextFormat format, - int need_copy) -{ - MText *mt; - int nchars = nitems; - int bytes = nitems; - - if (format == MTEXT_FORMAT_US_ASCII) - { - char *p = (char *) data, *pend = p + nitems; - - while (p < pend) - if (*p++ < 0) - MERROR (MERROR_MTEXT, NULL); - } - else if (format == MTEXT_FORMAT_UTF_8) - { - if ((nchars = count_utf_8_chars (data, nitems)) < 0) - MERROR (MERROR_MTEXT, NULL); - } - else if (format <= MTEXT_FORMAT_UTF_16BE) - { - if ((nchars = count_utf_16_chars (data, nitems, - format != default_utf_16)) < 0) - MERROR (MERROR_MTEXT, NULL); - bytes = sizeof (short) * nitems; - } - else if (format <= MTEXT_FORMAT_UTF_32BE) - { - unsigned *p = (unsigned *) data, *pend = p + nitems; - int swap = format != default_utf_32; - - for (; p < pend; p++) - { - unsigned c = swap ? SWAP_32 (*p) : *p; - - if ((c >= 0xD800 && c < 0xE000) || (c >= 0x110000)) - MERROR (MERROR_MTEXT, NULL); - } - bytes = sizeof (unsigned) * nitems; - } - else - MERROR (MERROR_MTEXT, NULL); - - mt = mtext (); - mt->format = format; - mt->allocated = need_copy ? bytes : -1; - mt->nchars = nchars; - mt->nbytes = nitems; - if (need_copy) - { - mt->data = malloc (bytes + 1); - memcpy (mt->data, data, bytes); - mt->data[bytes] = 0; - } - else - mt->data = (unsigned char *) data; - return mt; -} - - -int -mtext__replace (MText *mt, int from, int to, char *from_str, char *to_str) -{ - int from_byte = POS_CHAR_TO_BYTE (mt, from); - int to_byte = POS_CHAR_TO_BYTE (mt, to); - unsigned char *p = MTEXT_DATA (mt) + from_byte; - unsigned char *endp = MTEXT_DATA (mt) + to_byte; - int from_str_len = strlen (from_str); - int to_str_len = strlen (to_str); - int diff = to_str_len - from_str_len; - unsigned char saved_byte; - int pos, pos_byte; - - if (mtext_nchars (mt) == 0 - || from_str_len == 0) - return 0; - M_CHECK_READONLY (mt, -1); - M_CHECK_RANGE (mt, from, to, -1, 0); - - saved_byte = *endp; - *endp = '\0'; - while ((p = (unsigned char *) strstr ((char *) p, from_str)) != NULL) - { - if (diff < 0) - { - pos_byte = p - MTEXT_DATA (mt); - pos = POS_BYTE_TO_CHAR (mt, pos_byte); - mtext_del (mt, pos, pos - diff); - } - else if (diff > 0) - { - pos_byte = p - MTEXT_DATA (mt); - pos = POS_BYTE_TO_CHAR (mt, pos_byte); - mtext_ins_char (mt, pos, ' ', diff); - /* The above may relocate mt->data. */ - endp += (MTEXT_DATA (mt) + pos_byte) - p; - p = MTEXT_DATA (mt) + pos_byte; - } - memmove (p, to_str, to_str_len); - p += to_str_len; - endp += diff; - } - *endp = saved_byte; - return 0; -} - - -/* Find the position of a character at the beginning of a line of - M-Text MT searching backward from POS. */ - -int -mtext__bol (MText *mt, int pos) -{ - int byte_pos; - - if (pos == 0) - return pos; - byte_pos = POS_CHAR_TO_BYTE (mt, pos); - if (mt->format <= MTEXT_FORMAT_UTF_8) - { - unsigned char *p = mt->data + byte_pos; - - if (p[-1] == '\n') - return pos; - p--; - while (p > mt->data && p[-1] != '\n') - p--; - if (p == mt->data) - return 0; - byte_pos = p - mt->data; - return POS_BYTE_TO_CHAR (mt, byte_pos); - } - else if (mt->format <= MTEXT_FORMAT_UTF_16BE) - { - unsigned short *p = ((unsigned short *) (mt->data)) + byte_pos; - unsigned short newline = mt->format == default_utf_16 ? 0x0A00 : 0x000A; - - if (p[-1] == newline) - return pos; - p--; - while (p > (unsigned short *) (mt->data) && p[-1] != newline) - p--; - if (p == (unsigned short *) (mt->data)) - return 0; - byte_pos = p - (unsigned short *) (mt->data); - return POS_BYTE_TO_CHAR (mt, byte_pos);; - } - else - { - unsigned *p = ((unsigned *) (mt->data)) + byte_pos; - unsigned newline = mt->format == default_utf_32 ? 0x0A000000 : 0x0000000A; - - if (p[-1] == newline) - return pos; - p--, pos--; - while (p > (unsigned *) (mt->data) && p[-1] != newline) - p--, pos--; - return pos; - } -} - - -/* Find the position of a character at the end of a line of M-Text MT - searching forward from POS. */ - -int -mtext__eol (MText *mt, int pos) -{ - int byte_pos; - - if (pos == mt->nchars) - return pos; - byte_pos = POS_CHAR_TO_BYTE (mt, pos); - if (mt->format <= MTEXT_FORMAT_UTF_8) - { - unsigned char *p = mt->data + byte_pos; - unsigned char *endp; - - if (*p == '\n') - return pos + 1; - p++; - endp = mt->data + mt->nbytes; - while (p < endp && *p != '\n') - p++; - if (p == endp) - return mt->nchars; - byte_pos = p + 1 - mt->data; - return POS_BYTE_TO_CHAR (mt, byte_pos); - } - else if (mt->format <= MTEXT_FORMAT_UTF_16BE) - { - unsigned short *p = ((unsigned short *) (mt->data)) + byte_pos; - unsigned short *endp; - unsigned short newline = mt->format == default_utf_16 ? 0x0A00 : 0x000A; - - if (*p == newline) - return pos + 1; - p++; - endp = (unsigned short *) (mt->data) + mt->nbytes; - while (p < endp && *p != newline) - p++; - if (p == endp) - return mt->nchars; - byte_pos = p + 1 - (unsigned short *) (mt->data); - return POS_BYTE_TO_CHAR (mt, byte_pos); - } - else - { - unsigned *p = ((unsigned *) (mt->data)) + byte_pos; - unsigned *endp; - unsigned newline = mt->format == default_utf_32 ? 0x0A000000 : 0x0000000A; - - if (*p == newline) - return pos + 1; - p++, pos++; - endp = (unsigned *) (mt->data) + mt->nbytes; - while (p < endp && *p != newline) - p++, pos++; - return pos; - } -} - -/*** @} */ -#endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */ - - -/* External API */ - -/*** @addtogroup m17nMtext */ -/*** @{ */ -/*=*/ - -/***en - @brief Allocate a new M-text. - - The mtext () function allocates a new M-text of length 0 and - returns a pointer to it. The allocated M-text will not be freed - unless the user explicitly does so with the m17n_object_free () - function. */ - -/***ja - @brief ¿·¤·¤¤M-text¤ò³ä¤êÅö¤Æ¤ë - - ´Ø¿ô mtext () ¤Ï¡¢Ä¹¤µ 0 ¤Î¿·¤·¤¤ M-text ¤ò³ä¤êÅö¤Æ¡¢¤½¤ì¤Ø¤Î¥Ý¥¤ - ¥ó¥¿¤òÊÖ¤¹¡£³ä¤êÅö¤Æ¤é¤ì¤¿ M-text ¤Ï¡¢´Ø¿ô m17n_object_free () ¤Ë - ¤è¤Ã¤Æ¥æ¡¼¥¶¤¬ÌÀ¼¨Åª¤Ë¹Ô¤Ê¤ï¤Ê¤¤¸Â¤ê¡¢²òÊü¤µ¤ì¤Ê¤¤¡£ - - @latexonly \IPAlabel{mtext} @endlatexonly */ - -/*** - @seealso - m17n_object_free () */ - -MText * -mtext () -{ - MText *mt; - - M17N_OBJECT (mt, free_mtext, MERROR_MTEXT); - mt->format = MTEXT_FORMAT_UTF_8; - M17N_OBJECT_REGISTER (mtext_table, mt); - return mt; -} - -/***en - @brief Allocate a new M-text with specified data. - - The mtext_from_data () function allocates a new M-text whose - character sequence is specified by array $DATA of $NITEMS - elements. $FORMAT specifies the format of $DATA. - - When $FORMAT is either #MTEXT_FORMAT_US_ASCII or - #MTEXT_FORMAT_UTF_8, the contents of $DATA must be of the type @c - unsigned @c char, and $NITEMS counts by byte. - - When $FORMAT is either #MTEXT_FORMAT_UTF_16LE or - #MTEXT_FORMAT_UTF_16BE, the contents of $DATA must be of the type - @c unsigned @c short, and $NITEMS counts by unsigned short. - - When $FORMAT is either #MTEXT_FORMAT_UTF_32LE or - #MTEXT_FORMAT_UTF_32BE, the contents of $DATA must be of the type - @c unsigned, and $NITEMS counts by unsigned. - - The character sequence of the M-text is not modifiable. - The contents of $DATA must not be modified while the M-text is alive. - - The allocated M-text will not be freed unless the user explicitly - does so with the m17n_object_free () function. Even in that case, - $DATA is not freed. - - @return - If the operation was successful, mtext_from_data () returns a - pointer to the allocated M-text. Otherwise it returns @c NULL and - assigns an error code to the external variable #merror_code. */ - -/*** - @errors - @c MERROR_MTEXT */ - -MText * -mtext_from_data (void *data, int nitems, enum MTextFormat format) -{ - if (nitems < 0) - MERROR (MERROR_MTEXT, NULL); - if (nitems == 0) - { - if (format == MTEXT_FORMAT_US_ASCII - || format == MTEXT_FORMAT_UTF_8) - { - unsigned char *p = data; - - while (*p++) nitems++; - } - else if (format <= MTEXT_FORMAT_UTF_16BE) - { - unsigned short *p = data; - - while (*p++) nitems++; - } - else if (format <= MTEXT_FORMAT_UTF_32BE) - { - unsigned *p = data; - - while (*p++) nitems++; - } - else - MERROR (MERROR_MTEXT, NULL); - } - return mtext__from_data (data, nitems, format, 0); -} - -/*=*/ - -/***en - @brief Number of characters in M-text. - - The mtext_len () function returns the number of characters in - M-text $MT. */ - -/***ja - @brief M-text Ãæ¤Îʸ»ú¿ô - - ´Ø¿ô mtext_len () ¤Ï M-text $MT Ãæ¤Îʸ»ú¿ô¤òÊÖ¤¹¡£ - - @latexonly \IPAlabel{mtext_len} @endlatexonly */ - -int -mtext_len (MText *mt) -{ - return (mt->nchars); -} - -/*=*/ - -/***en - @brief Return the character at the specified position in an M-text. - - The mtext_ref_char () function returns the character at $POS in - M-text $MT. If an error is detected, it returns -1 and assigns an - error code to the external variable #merror_code. */ - -/***ja - @brief M-text Ãæ¤Î»ØÄꤵ¤ì¤¿°ÌÃÖ¤Îʸ»ú¤òÊÖ¤¹ - - ´Ø¿ô mtext_ref_char () ¤Ï¡¢M-text $MT ¤Î°ÌÃÖ $POS ¤Îʸ»ú¤òÊÖ¤¹¡£ - ¥¨¥é¡¼¤¬¸¡½Ð¤µ¤ì¤¿¾ì¹ç¤Ï -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code - ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ - - @latexonly \IPAlabel{mtext_ref_char} @endlatexonly */ - -/*** - @errors - @c MERROR_RANGE */ - -int -mtext_ref_char (MText *mt, int pos) -{ - int c; - - M_CHECK_POS (mt, pos, -1); - if (mt->format <= MTEXT_FORMAT_UTF_8) - { - unsigned char *p = mt->data + POS_CHAR_TO_BYTE (mt, pos); - - c = STRING_CHAR (p); - } - else if (mt->format <= MTEXT_FORMAT_UTF_16BE) - { - unsigned short *p - = (unsigned short *) (mt->data) + POS_CHAR_TO_BYTE (mt, pos); - - if (mt->format == default_utf_16) - c = STRING_CHAR_UTF16 (p); - else - { - c = (*p >> 8) | ((*p & 0xFF) << 8); - if (c >= 0xD800 && c < 0xE000) - { - int c1 = (p[1] >> 8) | ((p[1] & 0xFF) << 8); - c = ((c - 0xD800) << 10) + (c1 - 0xDC00) + 0x10000; - } - } - } - else - { - unsigned *p = (unsigned *) (mt->data) + POS_CHAR_TO_BYTE (mt, pos); - - if (mt->format == default_utf_32) - c = *p; - else - c = SWAP_32 (*p); - } - return c; -} - -/*=*/ - -/***en - @brief Store a character into an M-text. - - The mtext_set_char () function sets character $C, which has no - text properties, at $POS in M-text $MT. - - @return - If the operation was successful, mtext_set_char () returns 0. - Otherwise it returns -1 and assigns an error code to the external - variable #merror_code. */ - -/***ja - @brief M-text ¤Ë°ìʸ»ú¤òÀßÄꤹ¤ë - - ´Ø¿ô mtext_set_char () ¤Ï¡¢¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£Ìµ¤·¤Îʸ»ú $C ¤ò - M-text $MT ¤Î $POS ¤Î°ÌÃÖ¤ËÀßÄꤹ¤ë¡£ - - @return - ½èÍý¤ËÀ®¸ù¤¹¤ì¤Ð mtext_set_char () ¤Ï 0 ¤òÊÖ¤¹¡£¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ - ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ - - @latexonly \IPAlabel{mtext_set_char} @endlatexonly */ - -/*** - @errors - @c MERROR_RANGE */ - -int -mtext_set_char (MText *mt, int pos, int c) -{ - int byte_pos; - int bytes_old, bytes_new; - int delta; - unsigned char str[MAX_UTF8_CHAR_BYTES]; - unsigned char *p; - int i; - - M_CHECK_POS (mt, pos, -1); - M_CHECK_READONLY (mt, -1); - - byte_pos = POS_CHAR_TO_BYTE (mt, pos); - p = mt->data + byte_pos; - bytes_old = CHAR_BYTES_AT (p); - bytes_new = CHAR_STRING (c, str); - delta = bytes_new - bytes_old; - - /* mtext__adjust_plist_for_change (mt, pos, pos + 1);*/ - - if (delta) - { - int byte_pos_old = byte_pos + bytes_old; - int byte_pos_new = byte_pos + bytes_new; - - if (mt->cache_char_pos > pos) - mt->cache_byte_pos += delta; - - if ((mt->allocated - mt->nbytes) <= delta) - { - mt->allocated = mt->nbytes + delta + 1; - MTABLE_REALLOC (mt->data, mt->allocated, MERROR_MTEXT); - } - - memmove (mt->data + byte_pos_old, mt->data + byte_pos_new, - mt->nbytes - byte_pos_old); - mt->nbytes += delta; - mt->data[mt->nbytes] = 0; - } - for (i = 0; i < bytes_new; i++) - mt->data[byte_pos + i] = str[i]; - return 0; -} - -/*=*/ - -/***en - @brief Append a character to an M-text. - - The mtext_cat_char () function appends character $C, which has no - text properties, to the end of M-text $MT. - - @return - This function returns a pointer to the resulting M-text $MT. If - $C is an invalid character, it returns @c NULL. */ - -/***ja - @brief M-text ¤Ë°ìʸ»úÄɲ乤ë - - ´Ø¿ô mtext_cat_char () ¤Ï¡¢¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£Ìµ¤·¤Îʸ»ú $C ¤ò - M-text $MT ¤ÎËöÈø¤ËÄɲ乤롣 - - @return - ¤³¤Î´Ø¿ô¤ÏÊѹ¹¤µ¤ì¤¿ M-text $MT ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£$C ¤¬Àµ¤·¤¤Ê¸ - »ú¤Ç¤Ê¤¤¾ì¹ç¤Ë¤Ï @c NULL ¤òÊÖ¤¹¡£ */ - -/*** - @seealso - mtext_cat (), mtext_ncat () */ - -MText * -mtext_cat_char (MText *mt, int c) -{ - unsigned char buf[MAX_UTF8_CHAR_BYTES]; - int nbytes; - int total_bytes; - - M_CHECK_READONLY (mt, NULL); - if (c < 0 || c > MCHAR_MAX) - return NULL; - nbytes = CHAR_STRING (c, buf); - - total_bytes = mt->nbytes + nbytes; - - mtext__adjust_plist_for_insert (mt, mt->nchars, 1, NULL); - - if (total_bytes >= mt->allocated) - { - mt->allocated = total_bytes + 1; - MTABLE_REALLOC (mt->data, mt->allocated, MERROR_MTEXT); - } - memcpy (mt->data + mt->nbytes, buf, nbytes); - mt->nbytes = total_bytes; - mt->nchars++; - mt->data[total_bytes] = 0; - return mt; -} - -/*=*/ - -/***en - @brief Create a copy of an M-text. - - The mtext_dup () function creates a copy of M-text $MT while - inheriting all the text properties of $MT. - - @return - This function returns a pointer to the created copy. */ - -/***ja - @brief M-text ¤Î¥³¥Ô¡¼¤òºî¤ë - - ´Ø¿ô mtext_dup () ¤Ï¡¢M-text $MT ¤Î¥³¥Ô¡¼¤òºî¤ë¡£$MT ¤Î¥Æ¥­¥¹¥È¥× - ¥í¥Ñ¥Æ¥£¤Ï¤¹¤Ù¤Æ·Ñ¾µ¤µ¤ì¤ë¡£ - - @return - ¤³¤Î´Ø¿ô¤Ïºî¤é¤ì¤¿¥³¥Ô¡¼¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£ - - @latexonly \IPAlabel{mtext_dup} @endlatexonly */ - -/*** - @seealso - mtext_duplicate () */ - -MText * -mtext_dup (MText *mt) -{ - return copy (mtext (), 0, mt, 0, mt->nchars); -} - -/*=*/ - -/***en - @brief Append an M-text to another. - - The mtext_cat () function appends M-text $MT2 to the end of M-text - $MT1 while inheriting all the text properties. $MT2 itself is not - modified. - - @return - This function returns a pointer to the resulting M-text $MT1. */ - -/***ja - @brief 2¸Ä¤Î M-text¤òÏ¢·ë¤¹¤ë - - ´Ø¿ô mtext_cat () ¤Ï¡¢ M-text $MT2 ¤ò M-text $MT1 ¤ÎËöÈø¤ËÉÕ¤±²Ã¤¨ - ¤ë¡£$MT2 ¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Ï¤¹¤Ù¤Æ·Ñ¾µ¤µ¤ì¤ë¡£$MT2 ¤ÏÊѹ¹¤µ¤ì¤Ê - ¤¤¡£ - - @return - ¤³¤Î´Ø¿ô¤ÏÊѹ¹¤µ¤ì¤¿ M-text $MT1 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£ - - @latexonly \IPAlabel{mtext_cat} @endlatexonly */ - -/*** - @seealso - mtext_ncat (), mtext_cat_char () */ - -MText * -mtext_cat (MText *mt1, MText *mt2) -{ - M_CHECK_READONLY (mt1, NULL); - - return copy (mt1, mt1->nchars, mt2, 0, mt2->nchars); -} - - -/*=*/ - -/***en - @brief Append a part of an M-text to another. - - The mtext_ncat () function appends the first $N characters of - M-text $MT2 to the end of M-text $MT1 while inheriting all the - text properties. If the length of $MT2 is less than $N, all - characters are copied. $MT2 is not modified. - - @return - If the operation was successful, mtext_ncat () returns a pointer - to the resulting M-text $MT1. If an error is detected, it returns - @c NULL and assigns an error code to the global variable @c - merror_code. */ - - -/***ja - @brief M-text ¤Î°ìÉô¤òÊ̤ΠM-text ¤ËÉղ乤ë - - ´Ø¿ô mtext_ncat () ¤Ï¡¢M-text $MT2 ¤Î¤Ï¤¸¤á¤Î $N ʸ»ú¤ò M-text - $MT1 ¤ÎËöÈø¤ËÉÕ¤±²Ã¤¨¤ë¡£$MT2 ¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Ï¤¹¤Ù¤Æ·Ñ¾µ¤µ¤ì - ¤ë¡£$MT2 ¤ÎŤµ¤¬ $N °Ê²¼¤Ê¤é¤Ð¡¢$MT2 ¤Î¤¹¤Ù¤Æ¤Îʸ»ú¤¬Éղ䵤ì¤ë¡£ - $N ¤¬Éé¤Î¾ì¹ç¡¢$MT1 ¤ÏÊѹ¹¤µ¤ì¤Ê¤¤¡£ - $MT2 ¤ÏÊѹ¹¤µ¤ì¤Ê¤¤¡£ - - @return - ½èÍý¤¬À®¸ù¤·¤¿¾ì¹ç¡¢mtext_ncat () ¤ÏÊѹ¹¤µ¤ì¤¿ M-text $MT1 ¤Ø¤Î¥Ý - ¥¤¥ó¥¿¤òÊÖ¤¹¡£¥¨¥é¡¼¤¬¸¡½Ð¤µ¤ì¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô @c - merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ - - @latexonly \IPAlabel{mtext_ncat} @endlatexonly */ - -/*** - @errors - @c MERROR_RANGE - - @seealso - mtext_cat (), mtext_cat_char () */ - -MText * -mtext_ncat (MText *mt1, MText *mt2, int n) -{ - M_CHECK_READONLY (mt1, NULL); - if (n < 0) - MERROR (MERROR_RANGE, NULL); - return copy (mt1, mt1->nchars, mt2, 0, mt2->nchars < n ? mt2->nchars : n); -} - - -/*=*/ - -/***en - @brief Copy an M-text to another. - - The mtext_cpy () function copies M-text $MT2 to M-text $MT1 while - inheriting all the text properties. The old text in $MT1 is - overwritten and the length of $MT1 is extended if necessary. $MT2 - is not modified. - - @return - This function returns a pointer to the resulting M-text $MT1. */ - -/***ja - @brief M-text ¤ò¥³¥Ô¡¼¤¹¤ë - - ´Ø¿ô mtext_cpy () ¤Ï M-text $MT2 ¤ò M-text $MT1 ¤Ë¾å½ñ¤­¥³¥Ô¡¼¤¹¤ë¡£ - $MT2 ¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Ï¤¹¤Ù¤Æ·Ñ¾µ¤µ¤ì¤ë¡£$MT1 ¤ÎŤµ¤ÏɬÍפ˱þ - ¤¸¤Æ¿­¤Ð¤µ¤ì¤ë¡£$MT2 ¤ÏÊѹ¹¤µ¤ì¤Ê¤¤¡£ - - @return - ¤³¤Î´Ø¿ô¤ÏÊѹ¹¤µ¤ì¤¿ M-text $MT1 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£ - - @latexonly \IPAlabel{mtext_cpy} @endlatexonly */ - -/*** - @seealso - mtext_ncpy (), mtext_copy () */ - -MText * -mtext_cpy (MText *mt1, MText *mt2) -{ - M_CHECK_READONLY (mt1, NULL); - return copy (mt1, 0, mt2, 0, mt2->nchars); -} - -/*=*/ - -/***en - @brief Copy the first some characters in an M-text to another. - - The mtext_ncpy () function copies the first $N characters of - M-text $MT2 to M-text $MT1 while inheriting all the text - properties. If the length of $MT2 is less than $N, all characters - of $MT2 are copied. The old text in $MT1 is overwritten and the - length of $MT1 is extended if necessary. $MT2 is not modified. - - @return - If the operation was successful, mtext_ncpy () returns a pointer - to the resulting M-text $MT1. If an error is detected, it returns - @c NULL and assigns an error code to the global variable @c - merror_code. */ - -/***ja - @brief M-text ¤Ë´Þ¤Þ¤ì¤ëºÇ½é¤Î²¿Ê¸»ú¤«¤ò¥³¥Ô¡¼¤¹¤ë - - ´Ø¿ô mtext_ncpy () ¤Ï¡¢M-text $MT2 ¤ÎºÇ½é¤Î $N ʸ»ú¤ò M-text $MT1 - ¤Ë¾å½ñ¤­¥³¥Ô¡¼¤¹¤ë¡£¤â¤· $MT2 ¤ÎŤµ¤¬ $N ¤è¤ê¤â¾®¤µ¤±¤ì¤Ð $MT2 ¤Î - ¤¹¤Ù¤Æ¤Îʸ»ú¤ò¥³¥Ô¡¼¤¹¤ë¡£$MT2 ¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Ï¤¹¤Ù¤Æ·Ñ¾µ¤µ - ¤ì¤ë¡£$MT1 ¤ÎŤµ¤ÏɬÍפ˱þ¤¸¤Æ¿­¤Ð¤µ¤ì¤ë¡£$MT2 ¤ÏÊѹ¹¤µ¤ì¤Ê¤¤¡£ - - @return - ½èÍý¤¬À®¸ù¤·¤¿¾ì¹ç¡¢mtext_ncpy () ¤ÏÊѹ¹¤µ¤ì¤¿ M-text$MT1 ¤Ø¤Î¥Ý¥¤ - ¥ó¥¿¤òÊÖ¤¹¡£¥¨¥é¡¼¤¬¸¡½Ð¤µ¤ì¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô @c - merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ - - @latexonly \IPAlabel{mtext_ncpy} @endlatexonly */ - -/*** - @errors - @c MERROR_RANGE - - @seealso - mtext_cpy (), mtext_copy () */ - -MText * -mtext_ncpy (MText *mt1, MText *mt2, int n) -{ - M_CHECK_READONLY (mt1, NULL); - if (n < 0) - MERROR (MERROR_RANGE, NULL); - return (copy (mt1, 0, mt2, 0, mt2->nchars < n ? mt2->nchars : n)); -} - -/*=*/ - -/***en - @brief Create a new M-text from a part of an existing M-text. - - The mtext_duplicate () function creates a copy of sub-text of - M-text $MT, starting at $FROM (inclusive) and ending at $TO - (exclusive) while inheriting all the text properties of $MT. $MT - itself is not modified. - - @return - If the operation was successful, mtext_duplicate () returns a - pointer to the created M-text. If an error is detected, it returns 0 - and assigns an error code to the external variable #merror_code. */ - -/***ja - @brief M-text ¤Î°ìÉô¤«¤é¿·¤·¤¤ M-text ¤ò¤Ä¤¯¤ë - - ´Ø¿ô mtext_duplicate () ¤Ï¡¢M-text $MT ¤Î $FROM ¡Ê´Þ¤à¡Ë¤«¤é $TO - ¡Ê´Þ¤Þ¤Ê¤¤¡Ë¤Þ¤Ç¤ÎÉôʬʸ»úÎó¤Î¥³¥Ô¡¼¤òºî¤ë¡£¤³¤Î¤È¤­ $MT ¤Î¥Æ¥­¥¹ - ¥È¥×¥í¥Ñ¥Æ¥£¤Ï¤¹¤Ù¤Æ·Ñ¾µ¤µ¤ì¤ë¡£$MT ¤½¤Î¤â¤Î¤ÏÊѹ¹¤µ¤ì¤Ê¤¤¡£ - - @return - ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¡¢mtext_duplicate () ¤Ïºî¤é¤ì¤¿ M-text ¤Ø¤Î¥Ý¥¤¥ó - ¥¿¤òÊÖ¤¹¡£¥¨¥é¡¼¤¬¸¡½Ð¤µ¤ì¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code - ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ - - @latexonly \IPAlabel{mtext_duplicate} @endlatexonly */ - -/*** - @errors - @c MERROR_RANGE - - @seealso - mtext_dup () */ - -MText * -mtext_duplicate (MText *mt, int from, int to) -{ - MText *new = mtext (); - - M_CHECK_RANGE (mt, from, to, NULL, new); - return copy (new, 0, mt, from, to); -} - -/*=*/ - -/***en - @brief Copy characters in the specified range into an M-text. - - The mtext_copy () function copies the text between $FROM - (inclusive) and $TO (exclusive) in M-text $MT2 to the region - starting at $POS in M-text $MT1 while inheriting the text - properties. The old text in $MT1 is overwritten and the length of - $MT1 is extended if necessary. $MT2 is not modified. - - @return - If the operation was successful, mtext_copy () returns a pointer - to the modified $MT1. Otherwise, it returns @c NULL and assigns - an error code to the external variable #merror_code. */ - -/***ja - @brief M-text ¤Î»ØÄêÈϰϤÎʸ»ú¤ò¥³¥Ô¡¼¤¹¤ë - - ´Ø¿ô mtext_copy () ¤Ï¡¢ M-text $MT2 ¤Î $FROM ¡Ê´Þ¤à¡Ë¤«¤é $TO ¡Ê´Þ - ¤Þ¤Ê¤¤¡Ë¤Þ¤Ç¤ÎÈϰϤΥƥ­¥¹¥È¤ò M-text $MT1 ¤Î°ÌÃÖ $POS ¤«¤é¾å½ñ¤­ - ¥³¥Ô¡¼¤¹¤ë¡£$MT2 ¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Ï¤¹¤Ù¤Æ·Ñ¾µ¤µ¤ì¤ë¡£$MT1 ¤ÎĹ - ¤µ¤ÏɬÍפ˱þ¤¸¤Æ¿­¤Ð¤µ¤ì¤ë¡£$MT2 ¤ÏÊѹ¹¤µ¤ì¤Ê¤¤¡£ - - @latexonly \IPAlabel{mtext_copy} @endlatexonly - - @return - ½èÍý¤¬À®¸ù¤·¤¿¾ì¹ç¡¢mtext_copy () ¤ÏÊѹ¹¤µ¤ì¤¿ $MT1 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤ò - ÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼ - ¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ */ - -/*** - @errors - @c MERROR_RANGE - - @seealso - mtext_cpy (), mtext_ncpy () */ - -MText * -mtext_copy (MText *mt1, int pos, MText *mt2, int from, int to) -{ - M_CHECK_POS_X (mt1, pos, NULL); - M_CHECK_READONLY (mt1, NULL); - M_CHECK_RANGE (mt2, from, to, NULL, mt1); - return copy (mt1, pos, mt2, from, to); -} - -/*=*/ - - -/***en - @brief Delete characters in the specified range destructively. - - The mtext_del () function deletes the characters in the range - $FROM (inclusive) and $TO (exclusive) from M-text $MT - destructively. As a result, the length of $MT shrinks by ($TO - - $FROM) characters. - - @return - If the operation was successful, mtext_del () returns 0. - Otherwise, it returns -1 and assigns an error code to the external - variable #merror_code. */ - -/***ja - @brief »ØÄêÈϰϤÎʸ»ú¤òÇ˲õŪ¤Ë¼è¤ê½ü¤¯ - - ´Ø¿ô mtext_del () ¤Ï¡¢M-text $MT ¤Î $FROM ¡Ê´Þ¤à¡Ë¤«¤é $TO ¡Ê´Þ¤Þ - ¤Ê¤¤¡Ë¤Þ¤Ç¤Îʸ»ú¤òÇ˲õŪ¤Ë¼è¤ê½ü¤¯¡£·ë²ÌŪ¤Ë $MT ¤ÏŤµ¤¬ ($TO @c - - $FROM) ¤À¤±½Ì¤à¤³¤È¤Ë¤Ê¤ë¡£ - - @return - ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mtext_del () ¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ - ¤·¡¢Æ±»þ¤Ë³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ */ - -/*** - @errors - @c MERROR_RANGE - - @seealso - mtext_ins () */ - -int -mtext_del (MText *mt, int from, int to) -{ - int from_byte, to_byte; - - M_CHECK_READONLY (mt, -1); - M_CHECK_RANGE (mt, from, to, -1, 0); - - from_byte = POS_CHAR_TO_BYTE (mt, from); - to_byte = POS_CHAR_TO_BYTE (mt, to); - - if (mt->cache_char_pos >= to) - { - mt->cache_char_pos -= to - from; - mt->cache_byte_pos -= to_byte - from_byte; - } - else if (mt->cache_char_pos > from) - { - mt->cache_char_pos -= from; - mt->cache_byte_pos -= from_byte; - } - - mtext__adjust_plist_for_delete (mt, from, to - from); - memmove (mt->data + from_byte, mt->data + to_byte, mt->nbytes - to_byte + 1); - mt->nchars -= (to - from); - mt->nbytes -= (to_byte - from_byte); - mt->cache_char_pos = from; - mt->cache_byte_pos = from_byte; - return 0; -} - - -/*=*/ - -/***en - @brief Insert an M-text into another M-text. - - The mtext_ins () function inserts M-text $MT2 into M-text $MT1, at - position $POS. As a result, $MT1 is lengthen by the length of - $MT2. On insertion, all the text properties of $MT2 are - inherited. The original $MT2 is not modified. - - @return - If the operation was successful, mtext_ins () returns 0. - Otherwise, it returns -1 and assigns an error code to the external - variable #merror_code. */ - -/***ja - @brief M-text ¤òÊ̤ΠM-text ¤ËÁÞÆþ¤¹¤ë - - ´Ø¿ô mtext_ins () ¤Ï M-text $MT1 ¤Î $POS ¤Î°ÌÃÖ¤Ë Ê̤ΠM-text $MT2 - ¤òÁÞÆþ¤¹¤ë¡£¤³¤Î·ë²Ì $MT1 ¤ÎŤµ¤Ï $MT2 ¤Î¤Ö¤ó¤À¤±Áý¤¨¤ë¡£ÁÞÆþ¤ÎºÝ¡¢ - $MT2 ¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Ï¤¹¤Ù¤Æ·Ñ¾µ¤µ¤ì¤ë¡£$MT2 ¤½¤Î¤â¤Î¤ÏÊѹ¹¤µ - ¤ì¤Ê¤¤¡£ - - @return - ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mtext_ins () ¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ - ¤·¡¢Æ±»þ¤Ë³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ */ - -/*** - @errors - @c MERROR_RANGE - - @seealso - mtext_del () */ - -int -mtext_ins (MText *mt1, int pos, MText *mt2) -{ - int byte_pos; - int total_bytes; - - M_CHECK_READONLY (mt1, -1); - M_CHECK_POS_X (mt1, pos, -1); - - if (mt2->nchars == 0) - return 0; - mtext__adjust_plist_for_insert - (mt1, pos, mt2->nchars, - mtext__copy_plist (mt2->plist, 0, mt2->nchars, mt1, pos)); - - total_bytes = mt1->nbytes + mt2->nbytes; - if (total_bytes >= mt1->allocated) - { - mt1->allocated = total_bytes + 1; - MTABLE_REALLOC (mt1->data, mt1->allocated, MERROR_MTEXT); - } - byte_pos = POS_CHAR_TO_BYTE (mt1, pos); - if (mt1->cache_char_pos > pos) - { - mt1->cache_char_pos += mt2->nchars; - mt1->cache_byte_pos += mt2->nbytes; - } - memmove (mt1->data + byte_pos + mt2->nbytes, mt1->data + byte_pos, - mt1->nbytes - byte_pos + 1); - memcpy (mt1->data + byte_pos, mt2->data, mt2->nbytes); - mt1->nbytes += mt2->nbytes; - mt1->nchars += mt2->nchars; - return 0; -} - - -int -mtext_ins_char (MText *mt, int pos, int c, int n) -{ - int byte_pos; - int nbytes, total_bytes; - unsigned char *buf; - int i; - - M_CHECK_READONLY (mt, -1); - M_CHECK_POS_X (mt, pos, -1); - if (c < 0 || c > MCHAR_MAX) - MERROR (MERROR_MTEXT, -1); - if (n <= 0) - return 0; - mtext__adjust_plist_for_insert (mt, pos, n, NULL); - buf = alloca (MAX_UTF8_CHAR_BYTES * n); - for (i = 0, nbytes = 0; i < n; i++) - nbytes += CHAR_STRING (c, buf + nbytes); - total_bytes = mt->nbytes + nbytes; - if (total_bytes >= mt->allocated) - { - mt->allocated = total_bytes + 1; - MTABLE_REALLOC (mt->data, mt->allocated, MERROR_MTEXT); - } - byte_pos = POS_CHAR_TO_BYTE (mt, pos); - if (mt->cache_char_pos > pos) - { - mt->cache_char_pos++; - mt->cache_byte_pos += nbytes; - } - memmove (mt->data + byte_pos + nbytes, mt->data + byte_pos, - mt->nbytes - byte_pos + 1); - memcpy (mt->data + byte_pos, buf, nbytes); - mt->nbytes += nbytes; - mt->nchars += n; - return 0; -} - -/*=*/ - -/***en - @brief Search a character in an M-text. - - The mtext_character () function searches M-text $MT for character - $C. If $FROM < $TO, search begins at position $FROM and goes - forward but does not exceed ($TO - 1). Otherwise, search begins - at position ($FROM - 1) and goes backward but does not exceed $TO. - An invalid position specification is regarded as both $FROM and - $TO being 0. - - @return - If $C is found, mtext_character () returns the position of its - first occurrence. Otherwise it returns -1 without changing the - external variable #merror_code. If an error is detected, it returns -1 and - assigns an error code to the external variable #merror_code. */ - -/***ja - @brief M-text Ãæ¤ÎÆÃÄê¤Îʸ»ú¤òõ¤¹ - - ´Ø¿ô mtext_character () ¤Ï M-text $MT Ãæ¤Ë¤ª¤±¤ëʸ»ú $C ¤Î½Ð¸½°ÌÃÖ - ¤òÄ´¤Ù¤ë¡£¤â¤· $FROM < $TO ¤Ê¤é¤Ð¡¢Ãµº÷¤Ï°ÌÃÖ $FROM ¤«¤éËöÈøÊý¸þ¤Ø¡¢ - ºÇÂç ($TO - 1) ¤Þ¤Ç¿Ê¤à¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð°ÌÃÖ ($FROM - 1) ¤«¤éÀèƬÊý - ¸þ¤Ø¡¢ºÇÂç $TO ¤Þ¤Ç¿Ê¤à¡£°ÌÃ֤λØÄê¤Ë¸í¤ê¤¬¤¢¤ë¾ì¹ç¤Ï¡¢$FROM ¤È - $TO ¤ÎξÊý¤Ë 0 ¤¬»ØÄꤵ¤ì¤¿¤â¤Î¤È¸«¤Ê¤¹¡£ - - @return - ¤â¤· $C ¤¬¸«¤Ä¤«¤ì¤Ð¡¢mtext_character () ¤Ï¤½¤ÎºÇ½é¤Î½Ð¸½°ÌÃÖ¤òÊÖ - ¤¹¡£¸«¤Ä¤«¤é¤Ê¤«¤Ã¤¿¾ì¹ç¤Ï³°ÉôÊÑ¿ô #merror_code ¤òÊѹ¹¤»¤º¤Ë -1 ¤òÊÖ - ¤¹¡£¥¨¥é¡¼¤¬¸¡½Ð¤µ¤ì¤¿¾ì¹ç¤Ï -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼ - ¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ */ - -/*** - @seealso - mtext_chr(), mtext_rchr () */ - -int -mtext_character (MText *mt, int from, int to, int c) -{ - if (from < to) - { - /* We do not use M_CHECK_RANGE () because this function should - not set merror_code. */ - if (from < 0 || to > mt->nchars) - return -1; - return find_char_forward (mt, from, to, c); - } - else - { - /* ditto */ - if (to < 0 || from > mt->nchars) - return -1; - return find_char_backward (mt, to, from, c); - } -} - - -/*=*/ - -/***en - @brief Return the position of the first occurrence of a - character in an M-text. - - The mtext_chr () function searches M-text $MT for character $C. - Search starts from the beginning of $MT and goes toward the end. - - @return - If $C is found, mtext_chr () returns its position; otherwise it - returns. */ - -/***ja - @brief M-text Ãæ¤Ç»ØÄꤵ¤ì¤¿Ê¸»ú¤¬ºÇ½é¤Ë¸½¤ì¤ë°ÌÃÖ¤òÊÖ¤¹ - - ´Ø¿ô mtext_chr () ¤Ï M-text $MT Ãæ¤Ë¤ª¤±¤ëʸ»ú $C ¤Î½Ð¸½°ÌÃÖ¤òÄ´¤Ù - ¤ë¡£Ãµº÷¤Ï $MT ¤ÎÀèƬ¤«¤éËöÈøÊý¸þ¤Ë¿Ê¤à¡£ - - @return - ¤â¤· $C ¤¬¸«¤Ä¤«¤ì¤Ð¡¢mtext_chr () ¤Ï¤½¤Î½Ð¸½°ÌÃÖ¤òÊÖ¤¹¡£¸«¤Ä¤«¤é - ¤Ê¤«¤Ã¤¿¾ì¹ç¤Ï -1 ¤òÊÖ¤¹¡£ - - @latexonly \IPAlabel{mtext_chr} @endlatexonly */ - -/*** - @errors - @c MERROR_RANGE - - @seealso - mtext_rchr (), mtext_character () */ - -int -mtext_chr (MText *mt, int c) -{ - return find_char_forward (mt, 0, mt->nchars, c); -} - -/*=*/ - -/***en - @brief Return the position of the last occurrence of a - character in an M-text. - - The mtext_rchr () function searches M-text $MT for character $C. - Search starts from the end of $MT and goes backwardly toward the - beginning. - - @return - If $C is found, mtext_chr () returns its position; otherwise it - returns -1. */ - -/***ja - @brief M-text Ãæ¤Ç»ØÄꤵ¤ì¤¿Ê¸»ú¤¬ºÇ¸å¤Ë¸½¤ì¤ë°ÌÃÖ¤òÊÖ¤¹ - - ´Ø¿ô mtext_rchr () ¤Ï M-text $MT Ãæ¤Ë¤ª¤±¤ëʸ»ú $C ¤Î½Ð¸½°ÌÃÖ¤òÄ´ - ¤Ù¤ë¡£Ãµº÷¤Ï $MT ¤ÎºÇ¸å¤«¤éÀèƬÊý¸þ¤Ø¤È¸å¸þ¤­¤Ë¿Ê¤à¡£ - - @return - ¤â¤· $C ¤¬¸«¤Ä¤«¤ì¤Ð¡¢mtext_chr () ¤Ï¤½¤Î½Ð¸½°ÌÃÖ¤òÊÖ¤¹¡£¸«¤Ä¤«¤é - ¤Ê¤«¤Ã¤¿¾ì¹ç¤Ï -1 ¤òÊÖ¤¹¡£ - - @latexonly \IPAlabel{mtext_rchr} @endlatexonly */ - -/*** - @errors - @c MERROR_RANGE - - @seealso - mtext_chr (), mtext_character () */ - -int -mtext_rchr (MText *mt, int c) -{ - return find_char_backward (mt, mt->nchars, 0, c); -} - - -/*=*/ - -/***en - @brief Compare two M-texts character-by-character. - - The mtext_cmp () function compares M-texts $MT1 and $MT2 character - by character. - - @return - This function returns 1, 0, or -1 if $MT1 is found greater than, - equal to, or less than $MT2, respectively. Comparison is based on - character codes. */ - -/***ja - @brief Æó¤Ä¤Î M-text ¤òʸ»úñ°Ì¤ÇÈæ³Ó¤¹¤ë - - ´Ø¿ô mtext_cmp () ¤Ï¡¢ M-text $MT1 ¤È $MT2 ¤òʸ»úñ°Ì¤ÇÈæ³Ó¤¹¤ë¡£ - - @return - ¤³¤Î´Ø¿ô¤Ï¡¢$MT1 ¤È $MT2 ¤¬Åù¤·¤±¤ì¤Ð 0¡¢$MT1 ¤¬ $MT2 ¤è¤êÂ礭¤±¤ì - ¤Ð 1¡¢$MT1 ¤¬ $MT2 ¤è¤ê¾®¤µ¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£Èæ³Ó¤Ïʸ»ú¥³¡¼¥É¤Ë´ð¤Å - ¤¯¡£ - - @latexonly \IPAlabel{mtext_cmp} @endlatexonly */ - -/*** - @seealso - mtext_ncmp (), mtext_casecmp (), mtext_ncasecmp (), - mtext_compare (), mtext_case_compare () */ - -int -mtext_cmp (MText *mt1, MText *mt2) -{ - return compare (mt1, 0, mt1->nchars, mt2, 0, mt2->nchars); -} - - -/*=*/ - -/***en - @brief Compare two M-texts character-by-character. - - The mtext_ncmp () function is similar to mtext_cmp (), but - compares at most $N characters from the beginning. - - @return - This function returns 1, 0, or -1 if $MT1 is found greater than, - equal to, or less than $MT2, respectively. */ - -/***ja - @brief Æó¤Ä¤Î M-text ¤òʸ»úñ°Ì¤ÇÈæ³Ó¤¹¤ë - - ´Ø¿ô mtext_ncmp () ¤Ï¡¢´Ø¿ô mtext_cmp () ƱÍͤΠM-text Ʊ»Î¤ÎÈæ³Ó - ¤òÀèƬ¤«¤éºÇÂç $N ʸ»ú¤Þ¤Ç¤Ë´Ø¤·¤Æ¹Ô¤Ê¤¦¡£ - - @return - ¤³¤Î´Ø¿ô¤Ï¡¢$MT1 ¤È $MT2 ¤¬Åù¤·¤±¤ì¤Ð 0¡¢$MT1 ¤¬ $MT2 ¤è¤êÂ礭¤±¤ì - ¤Ð 1¡¢$MT1 ¤¬ $MT2 ¤è¤ê¾®¤µ¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£ - - @latexonly \IPAlabel{mtext_ncmp} @endlatexonly */ - -/*** - @seealso - mtext_cmp (), mtext_casecmp (), mtext_ncasecmp () - mtext_compare (), mtext_case_compare () */ - -int -mtext_ncmp (MText *mt1, MText *mt2, int n) -{ - if (n < 0) - return 0; - return compare (mt1, 0, (mt1->nchars < n ? mt1->nchars : n), - mt2, 0, (mt2->nchars < n ? mt2->nchars : n)); -} - -/*=*/ - -/***en - @brief Compare two M-texts. - - The mtext_compare () function compares two M-texts $MT1 and $MT2, - character-by-character. The compared regions are between $FROM1 - and $TO1 in $MT1 and $FROM2 to $TO2 in MT2. $FROM1 and $FROM2 are - inclusive, $TO1 and $TO2 are exclusive. $FROM1 being equal to - $TO1 (or $FROM2 being equal to $TO2) means an M-text of length - zero. An invalid region specification is regarded as both $FROM1 - and $TO1 (or $FROM2 and $TO2) being 0. - - @return - This function returns 1, 0, or -1 if $MT1 is found greater than, - equal to, or less than $MT2, respectively. Comparison is based on - character codes. */ - -/***ja - @brief Æó¤Ä¤Î M-text ¤òÈæ³Ó¤¹¤ë - - ´Ø¿ô mtext_compare () ¤ÏÆó¤Ä¤Î M-text $MT1 ¤È $MT2 ¤òʸ»úñ°Ì¤ÇÈæ - ³Ó¤¹¤ë¡£Èæ³ÓÂоݤȤʤë¤Î¤Ï $MT1 ¤Ç¤Ï $FROM1 ¤«¤é $TO1 ¤Þ¤Ç¡¢$MT2 - ¤Ç¤Ï $FROM2 ¤«¤é $TO2 ¤Þ¤Ç¤Ç¤¢¤ë¡£$FROM1 ¤È $FROM2 ¤Ï´Þ¤Þ¤ì¡¢$TO1 - ¤È $TO2 ¤Ï´Þ¤Þ¤ì¤Ê¤¤¡£$FROM1 ¤È $TO1 ¡Ê¤¢¤ë¤¤¤Ï $FROM2 ¤È $TO2 ¡Ë - ¤¬Åù¤·¤¤¾ì¹ç¤ÏŤµ¥¼¥í¤Î M-text ¤ò°ÕÌ£¤¹¤ë¡£ÈÏ°Ï»ØÄê¤Ë¸í¤ê¤¬¤¢¤ë¾ì - ¹ç¤Ï¡¢$FROM1 ¤È $TO1 ¡Ê¤¢¤ë¤¤¤Ï $FROM2 ¤È $TO2 ¡Ë ξÊý¤Ë 0 ¤¬»ØÄꤵ - ¤ì¤¿¤â¤Î¤È¸«¤Ê¤¹¡£ - - @return - ¤³¤Î´Ø¿ô¤Ï¡¢$MT1 ¤È $MT2 ¤¬Åù¤·¤±¤ì¤Ð 0¡¢$MT1 ¤¬ $MT2 ¤è¤êÂ礭¤±¤ì - ¤Ð 1 ¡¢$MT1 ¤¬ $MT2 ¤è¤ê¾®¤µ¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£Èæ³Ó¤Ïʸ»ú¥³¡¼¥É¤Ë´ð - ¤Å¤¯¡£ */ - -/*** - @seealso - mtext_cmp (), mtext_ncmp (), mtext_casecmp (), mtext_ncasecmp (), - mtext_case_compare () */ - -int -mtext_compare (MText *mt1, int from1, int to1, MText *mt2, int from2, int to2) -{ - if (from1 < 0 || from1 > to1 || to1 > mt1->nchars) - from1 = to1 = 0; - - if (from2 < 0 || from2 > to2 || to2 > mt2->nchars) - from2 = to2 = 0; - - return compare (mt1, from1, to1, mt2, from2, to2); -} - -/*=*/ - -/***en - @brief Search an M-text for a set of characters. - - The mtext_spn () function returns the length of the initial - segment of M-text $MT1 that consists entirely of characters in - M-text $MT2. */ - -/***ja - @brief ¤¢¤ëʸ»ú¤Î½¸¹ç¤ò M-text ¤ÎÃæ¤Çõ¤¹ - - ´Ø¿ô mtext_spn () ¤Ï¡¢M-text $MT1 ¤ÎÀèƬÉôʬ¤Ç M-text $MT2 ¤Ë´Þ¤Þ - ¤ì¤ëʸ»ú¤À¤±¤Ç¤Ç¤­¤Æ¤¤¤ëÉôʬ¤ÎºÇÂ獵¤ò·×»»¤¹¤ë¡£ - - @latexonly \IPAlabel{mtext_spn} @endlatexonly */ - -/*** - @seealso - mtext_cspn () */ - -int -mtext_spn (MText *mt, MText *accept) -{ - return span (mt, accept, 0, Mnil); -} - -/*=*/ - -/***en - @brief Search an M-text for the complement of a set of characters. - - The mtext_cspn () returns the length of the initial segment of - M-text $MT1 that consists entirely of characters not in M-text $MT2. */ - -/***ja - @brief ¤¢¤ë½¸¹ç¤Ë°¤µ¤Ê¤¤Ê¸»ú¤ò M-text ¤ÎÃæ¤Çõ¤¹ - - ´Ø¿ô mtext_cspn () ¤Ï¡¢M-text $MT1 ¤ÎÀèƬÉôʬ¤Ç M-text $MT2 ¤Ë´Þ¤Þ - ¤ì¤Ê¤¤Ê¸»ú¤À¤±¤Ç¤Ç¤­¤Æ¤¤¤ëÉôʬ¤ÎºÇÂ獵¤òÊÖ¤¹¡£ - - @latexonly \IPAlabel{mtext_cspn} @endlatexonly */ - -/*** - @seealso - mtext_spn () */ - -int -mtext_cspn (MText *mt, MText *reject) -{ - return span (mt, reject, 0, Mt); -} - -/*=*/ - -/***en - @brief Search an M-text for any of a set of characters - - The mtext_pbrk () function locates the first occurrence in M-text - $MT1 of any of the characters in M-text $MT2. - - @return - This function returns the position in $MT1 of the found character. - If no such character is found, it returns -1. */ - -/***ja - @brief Ê̤ΠM-text ¤Ë´Þ¤Þ¤ì¤ëʸ»ú¤ÎºÇ½é¤Î½Ð¸½°ÌÃÖ¤ò¸«¤Ä¤±¤ë - - ´Ø¿ô mtext_pbrk () ¤Ï¡¢M-text $MT1 Ãæ¤Ç M-text $MT2 ¤Î¤¤¤º¤ì¤«¤Îʸ - »ú¤¬ºÇ½é¤Ë¸½¤ì¤ë°ÌÃÖ¤òÄ´¤Ù¤ë¡£ - - @return - ¸«¤Ä¤«¤Ã¤¿Ê¸»ú¤Î¡¢$MT1 Æâ¤Ë¤ª¤±¤ë½Ð¸½°ÌÃÖ¤òÊÖ¤¹¡£¤â¤·¤½¤Î¤è¤¦¤Êʸ - »ú¤¬¸«¤Ä¤«¤é¤Ê¤«¤Ã¤¿¾ì¹ç¤Ï -1 ¤òÊÖ¤¹¡£ - - @latexonly \IPAlabel{mtext_pbrk} @endlatexonly */ - -int -mtext_pbrk (MText *mt, MText *accept) -{ - int nchars = mtext_nchars (mt); - int len = span (mt, accept, 0, Mt); - - return (len == nchars ? -1 : len); -} - -/*=*/ - -/***en - @brief Look for a token in an M-text - - The mtext_tok () function searches a token that firstly occurs - after position $POS in M-text $MT. Here, a token means a - substring each of which does not appear in M-text $DELIM. Note - that the type of $POS is not @c int but pointer to @c int. - - @return - If a token is found, mtext_tok () copies the corresponding part of - $MT and returns a pointer to the copy. In this case, $POS is set - to the end of the found token. If no token is found, it returns - @c NULL without changing the external variable #merror_code. If an - error is detected, it returns @c NULL and assigns an error code - to the external variable #merror_code. */ - -/***ja - @brief M-text Ãæ¤Î¥È¡¼¥¯¥ó¤òõ¤¹ - - ´Ø¿ô mtext_tok () ¤Ï¡¢M-text $MT ¤ÎÃæ¤Ç $POS °Ê¹ßºÇ½é¤Ë¸½¤ì¤ë¥È¡¼ - ¥¯¥ó¤òõ¤¹¡£¤³¤³¤Ç¥È¡¼¥¯¥ó¤È¤Ï M-text $DELIM ¤ÎÃæ¤Ë¸½¤ï¤ì¤Ê¤¤Ê¸»ú - ¤À¤±¤«¤é¤Ê¤ëÉôʬʸ»úÎó¤Ç¤¢¤ë¡£$POS ¤Î·¿¤¬ @c int ¤Ç¤Ï¤Ê¤¯¤Æ @c int - ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¤³¤È¤ËÃí°Õ¡£ - - @return - ¤â¤·¥È¡¼¥¯¥ó¤¬¸«¤Ä¤«¤ì¤Ð mtext_tok ()¤Ï¤½¤Î¥È¡¼¥¯¥ó¤ËÁêÅö¤¹¤ëÉôʬ - ¤Î $MT ¤ò¥³¥Ô¡¼¤·¡¢¤½¤Î¥³¥Ô¡¼¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢$POS ¤Ï - ¸«¤Ä¤«¤Ã¤¿¥È¡¼¥¯¥ó¤Î½ªÃ¼¤Ë¥»¥Ã¥È¤µ¤ì¤ë¡£¥È¡¼¥¯¥ó¤¬¸«¤Ä¤«¤é¤Ê¤«¤Ã¤¿ - ¾ì¹ç¤Ï³°ÉôÊÑ¿ô #merror_code ¤òÊѤ¨¤º¤Ë @c NULL ¤òÊÖ¤¹¡£¥¨¥é¡¼¤¬¸¡½Ð - ¤µ¤ì¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤·¡¢ÊÑÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤ò - ÀßÄꤹ¤ë¡£ - - @latexonly \IPAlabel{mtext_tok} @endlatexonly */ - -/*** - @errors - @c MERROR_RANGE */ - -MText * -mtext_tok (MText *mt, MText *delim, int *pos) -{ - int nchars = mtext_nchars (mt); - int pos2; - - M_CHECK_POS (mt, *pos, NULL); - - /* - Skip delimiters starting at POS in MT. - Never do *pos += span(...), or you will change *pos - even though no token is found. - */ - pos2 = *pos + span (mt, delim, *pos, Mnil); - - if (pos2 == nchars) - return NULL; - - *pos = pos2 + span (mt, delim, pos2, Mt); - return (copy (mtext (), 0, mt, pos2, *pos)); -} - -/*=*/ - -/***en - @brief Locate an M-text in another. - - The mtext_text () function finds the first occurrence of M-text - $MT2 in M-text $MT1 after the position $POS while ignoring - difference of the text properties. - - @return - If $MT2 is found in $MT1, mtext_text () returns the position of it - first occurrence. Otherwise it returns -1. If $MT2 is empty, it - returns 0. */ - -/***ja - @brief M-text Ãæ¤ÎÊ̤ΠM-text ¤òõ¤¹ - - ´Ø¿ô mtext_text () ¤Ï¡¢M-text $MT1 Ãæ¤Ë¤ª¤±¤ë M-text $MT2 ¤ÎºÇ½é¤Î - ½Ð¸½°ÌÃÖ¤òÄ´¤Ù¤ë¡£¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Î°ã¤¤¤Ï̵»ë¤µ¤ì¤ë¡£ - - @return - $MT1 Ãæ¤Ë $MT2 ¤¬¸«¤Ä¤«¤ì¤Ð¡¢mtext_text() ¤Ï¤½¤ÎºÇ½é¤Î½Ð¸½°ÌÃÖ¤òÊÖ - ¤¹¡£¸«¤Ä¤«¤é¤Ê¤¤¾ì¹ç¤Ï -1 ¤òÊÖ¤¹¡£¤â¤· $MT2 ¤¬¶õ¤Ê¤é¤Ð 0 ¤òÊÖ¤¹¡£ - - @latexonly \IPAlabel{mtext_text} @endlatexonly */ - -int -mtext_text (MText *mt1, int pos, MText *mt2) -{ - int from = pos; - int pos_byte = POS_CHAR_TO_BYTE (mt1, pos); - int c = mtext_ref_char (mt2, 0); - int nbytes1 = mtext_nbytes (mt1); - int nbytes2 = mtext_nbytes (mt2); - int limit; - int use_memcmp = (mt1->format == mt2->format - || (mt1->format < MTEXT_FORMAT_UTF_8 - && mt2->format == MTEXT_FORMAT_UTF_8)); - int unit_bytes = (mt1->format <= MTEXT_FORMAT_UTF_8 ? 1 - : mt1->format <= MTEXT_FORMAT_UTF_16BE ? 2 - : 4); - - if (nbytes2 > pos_byte + nbytes1) - return -1; - pos_byte = nbytes1 - nbytes2; - limit = POS_BYTE_TO_CHAR (mt1, pos_byte); - - while (1) - { - if ((pos = mtext_character (mt1, from, limit, c)) < 0) - return -1; - pos_byte = POS_CHAR_TO_BYTE (mt1, pos); - if (use_memcmp - ? ! memcmp (mt1->data + pos_byte * unit_bytes, - mt2->data, nbytes2 * unit_bytes) - : ! compare (mt1, pos, mt2->nchars, mt2, 0, mt2->nchars)) - break; - from = pos + 1; - } - return pos; -} - -int -mtext_search (MText *mt1, int from, int to, MText *mt2) -{ - int c = mtext_ref_char (mt2, 0); - int from_byte; - int nbytes2 = mtext_nbytes (mt2); - - if (mt1->format > MTEXT_FORMAT_UTF_8 - || mt2->format > MTEXT_FORMAT_UTF_8) - MERROR (MERROR_MTEXT, -1); - - if (from < to) - { - to -= mtext_nchars (mt2); - if (from > to) - return -1; - while (1) - { - if ((from = find_char_forward (mt1, from, to, c)) < 0) - return -1; - from_byte = POS_CHAR_TO_BYTE (mt1, from); - if (! memcmp (mt1->data + from_byte, mt2->data, nbytes2)) - break; - from++; - } - } - else if (from > to) - { - from -= mtext_nchars (mt2); - if (from < to) - return -1; - while (1) - { - if ((from = find_char_backward (mt1, from, to, c)) < 0) - return -1; - from_byte = POS_CHAR_TO_BYTE (mt1, from); - if (! memcmp (mt1->data + from_byte, mt2->data, nbytes2)) - break; - from--; - } - } - - return from; -} - -/*=*/ - -/***en - @brief Compare two M-texts ignoring cases. - - The mtext_casecmp () function is similar to mtext_cmp (), but - ignores cases on comparison. - - @return - This function returns 1, 0, or -1 if $MT1 is found greater than, - equal to, or less than $MT2, respectively. */ - -/***ja - @brief Æó¤Ä¤Î M-text ¤òÂçʸ»ú¡¿¾®Ê¸»ú¤Î¶èÊ̤ò̵»ë¤·¤ÆÈæ³Ó¤¹¤ë - - ´Ø¿ô mtext_casecmp () ¤Ï¡¢´Ø¿ô mtext_cmp () ƱÍͤΠM-text Ʊ»Î¤ÎÈæ - ³Ó¤ò¡¢Âçʸ»ú¡¿¾®Ê¸»ú¤Î¶èÊ̤ò̵»ë¤·¤Æ¹Ô¤Ê¤¦¡£ - - @return - ¤³¤Î´Ø¿ô¤Ï¡¢$MT1 ¤È $MT2 ¤¬Åù¤·¤±¤ì¤Ð 0¡¢$MT1 ¤¬ $MT2 ¤è¤êÂ礭¤±¤ì - ¤Ð 1¡¢$MT1 ¤¬ $MT2 ¤è¤ê¾®¤µ¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£ - - @latexonly \IPAlabel{mtext_casecmp} @endlatexonly */ - -/*** - @seealso - mtext_cmp (), mtext_ncmp (), mtext_ncasecmp () - mtext_compare (), mtext_case_compare () */ - -int -mtext_casecmp (MText *mt1, MText *mt2) -{ - return case_compare (mt1, 0, mt1->nchars, mt2, 0, mt2->nchars); -} - -/*=*/ - -/***en - @brief Compare two M-texts ignoring cases. - - The mtext_ncasecmp () function is similar to mtext_casecmp (), but - compares at most $N characters from the beginning. - - @return - This function returns 1, 0, or -1 if $MT1 is found greater than, - equal to, or less than $MT2, respectively. */ - -/***ja - @brief Æó¤Ä¤Î M-text ¤òÂçʸ»ú¡¿¾®Ê¸»ú¤Î¶èÊ̤ò̵»ë¤·¤ÆÈæ³Ó¤¹¤ë - - ´Ø¿ô mtext_ncasecmp () ¤Ï¡¢´Ø¿ô mtext_casecmp () ƱÍͤΠM-text Ʊ - »Î¤ÎÈæ³Ó¤òÀèƬ¤«¤éºÇÂç $N ʸ»ú¤Þ¤Ç¤Ë´Ø¤·¤Æ¹Ô¤Ê¤¦¡£ - - @return - ¤³¤Î´Ø¿ô¤Ï¡¢$MT1 ¤È $MT2 ¤¬Åù¤·¤±¤ì¤Ð 0¡¢$MT1 ¤¬ $MT2 ¤è¤êÂ礭¤±¤ì - ¤Ð 1¡¢$MT1 ¤¬ $MT2 ¤è¤ê¾®¤µ¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£ - - @latexonly \IPAlabel{mtext_ncasecmp} @endlatexonly */ - -/*** - @seealso - mtext_cmp (), mtext_casecmp (), mtext_casecmp () - mtext_compare (), mtext_case_compare () */ - -int -mtext_ncasecmp (MText *mt1, MText *mt2, int n) -{ - if (n < 0) - return 0; - return case_compare (mt1, 0, (mt1->nchars < n ? mt1->nchars : n), - mt2, 0, (mt2->nchars < n ? mt2->nchars : n)); -} - -/*=*/ - -/***en - @brief Compare two M-texts ignoring cases. - - The mtext_case_compare () function compares two M-texts $MT1 and - $MT2, character-by-character, ignoring cases. The compared - regions are between $FROM1 and $TO1 in $MT1 and $FROM2 to $TO2 in - MT2. $FROM1 and $FROM2 are inclusive, $TO1 and $TO2 are - exclusive. $FROM1 being equal to $TO1 (or $FROM2 being equal to - $TO2) means an M-text of length zero. An invalid region - specification is regarded as both $FROM1 and $TO1 (or $FROM2 and - $TO2) being 0. - - @return - This function returns 1, 0, or -1 if $MT1 is found greater than, - equal to, or less than $MT2, respectively. Comparison is based on - character codes. */ - -/***ja - @brief Æó¤Ä¤Î M-text ¤ò¡¢Âçʸ»ú¡¿¾®Ê¸»ú¤Î¶èÊ̤ò̵»ë¤·¤¿Ê¸»úñ°Ì¤ÇÈæ³Ó¤¹¤ë - - ´Ø¿ô mtext_compare () ¤ÏÆó¤Ä¤Î M-text $MT1 ¤È $MT2 ¤ò¡¢Âçʸ»ú¡¿¾® - ʸ»ú¤Î¶èÊ̤ò̵»ë¤·¤Ä¤Äʸ»úñ°Ì¤ÇÈæ³Ó¤¹¤ë¡£Èæ³ÓÂоݤȤʤë¤Î¤Ï $MT1 - ¤Ç¤Ï $FROM1 ¤«¤é $TO1 ¤Þ¤Ç¡¢$MT2 ¤Ç¤Ï $FROM2 ¤«¤é $TO2 ¤Þ¤Ç¤Ç¤¢¤ë¡£ - $FROM1 ¤È $FROM2 ¤Ï´Þ¤Þ¤ì¡¢$TO1 ¤È $TO2 ¤Ï´Þ¤Þ¤ì¤Ê¤¤¡£$FROM1 ¤È - $TO1 ¡Ê¤¢¤ë¤¤¤Ï $FROM2 ¤È $TO2 ¡Ë¤¬Åù¤·¤¤¾ì¹ç¤ÏŤµ¥¼¥í¤Î M-text - ¤ò°ÕÌ£¤¹¤ë¡£ÈÏ°Ï»ØÄê¤Ë¸í¤ê¤¬¤¢¤ë¾ì¹ç¤Ï¡¢$FROM1 ¤È $TO1 ¡Ê¤¢¤ë¤¤¤Ï - $FROM2 ¤È $TO2 ¡ËξÊý¤Ë 0 ¤¬»ØÄꤵ¤ì¤¿¤â¤Î¤È¸«¤Ê¤¹¡£ - - @return - ¤³¤Î´Ø¿ô¤Ï¡¢$MT1 ¤È $MT2 ¤¬Åù¤·¤±¤ì¤Ð0¡¢$MT1 ¤¬ $MT2 ¤è¤êÂ礭¤±¤ì - ¤Ð1¡¢$MT1 ¤¬ $MT2 ¤è¤ê¾®¤µ¤±¤ì¤Ð-1¤òÊÖ¤¹¡£Èæ³Ó¤Ïʸ»ú¥³¡¼¥É¤Ë´ð¤Å¤¯¡£ - - @latexonly \IPAlabel{mtext_case_compare} @endlatexonly -*/ - -/*** - @seealso - mtext_cmp (), mtext_ncmp (), mtext_casecmp (), mtext_ncasecmp (), - mtext_compare () */ - -int -mtext_case_compare (MText *mt1, int from1, int to1, - MText *mt2, int from2, int to2) -{ - if (from1 < 0 || from1 > to1 || to1 > mt1->nchars) - from1 = to1 = 0; - - if (from2 < 0 || from2 > to2 || to2 > mt2->nchars) - from2 = to2 = 0; - - return case_compare (mt1, from1, to1, mt2, from2, to2); -} - -/*** @} */ - -#include - -/*** @addtogroup m17nDebug */ -/*=*/ -/*** @{ */ - -/***en - @brief Dump an M-text - - The mdebug_dump_mtext () function prints the M-text $MT in a human - readable way to the stderr. $INDENT specifies how many columns to - indent the lines but the first one. If $FULLP is zero, this - function prints only a character code sequence. Otherwise, it - prints the internal byte sequence and text properties as well. - - @return - This function returns $MT. */ - -MText * -mdebug_dump_mtext (MText *mt, int indent, int fullp) -{ - char *prefix = (char *) alloca (indent + 1); - int i; - unsigned char *p; - - memset (prefix, 32, indent); - prefix[indent] = 0; - - if (! fullp) - { - fprintf (stderr, "\""); - for (i = 0; i < mt->nbytes; i++) - { - int c = mt->data[i]; - if (c >= ' ' && c < 127) - fprintf (stderr, "%c", c); - else - fprintf (stderr, "\\x%02X", c); - } - fprintf (stderr, "\""); - return mt; - } - - fprintf (stderr, - "(mtext (size %d %d %d) (cache %d %d)", - mt->nchars, mt->nbytes, mt->allocated, - mt->cache_char_pos, mt->cache_byte_pos); - if (mt->nchars > 0) - { - fprintf (stderr, "\n%s (bytes \"", prefix); - for (i = 0; i < mt->nbytes; i++) - fprintf (stderr, "\\x%02x", mt->data[i]); - fprintf (stderr, "\")\n"); - fprintf (stderr, "%s (chars \"", prefix); - p = mt->data; - for (i = 0; i < mt->nchars; i++) - { - int len; - int c = STRING_CHAR_AND_BYTES (p, len); - - if (c >= ' ' && c < 127 && c != '\\' && c != '"') - fputc (c, stderr); - else - fprintf (stderr, "\\x%X", c); - p += len; - } - fprintf (stderr, "\")"); - if (mt->plist) - { - fprintf (stderr, "\n%s ", prefix); - dump_textplist (mt->plist, indent + 1); - } - } - fprintf (stderr, ")"); - return mt; -} - -/*** @} */ - -/* - Local Variables: - coding: euc-japan - End: -*/ diff --git a/src/mtext.h b/src/mtext.h deleted file mode 100644 index 75cfd7b..0000000 --- a/src/mtext.h +++ /dev/null @@ -1,68 +0,0 @@ -/* mtext.h -- header file for the M-text module. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -#ifndef _M17N_MTEXT_H_ -#define _M17N_MTEXT_H_ - -/** @file mtext.h - @brief Header for M-text handling. -*/ - -#define POS_CHAR_TO_BYTE(mt, pos) \ - (mtext_nchars (mt) == mtext_nbytes (mt) ? (pos) \ - : (pos) == (mt)->cache_char_pos ? (mt)->cache_byte_pos \ - : mtext__char_to_byte ((mt), (pos))) - -#define POS_BYTE_TO_CHAR(mt, pos_byte) \ - (mtext_nchars (mt) == mtext_nbytes (mt) ? (pos_byte) \ - : (pos_byte) == (mt)->cache_byte_pos ? (mt)->cache_char_pos \ - : mtext__byte_to_char ((mt), (pos_byte))) - - -#define MTEXT_DATA(mt) ((mt)->data) - -extern int mtext__char_to_byte (MText *mt, int pos); - -extern int mtext__byte_to_char (MText *mt, int pos_byte); - -extern void mtext__enlarge (MText *mt, int nbytes); - -extern int mtext__takein (MText *mt, int nchars, int nbytes); - -extern int mtext__cat_data (MText *mt, unsigned char *p, int nbytes, - enum MTextFormat format); - -#define MTEXT_CAT_ASCII(mt, str) \ - mtext__cat_data ((mt), (unsigned char *) (str), strlen (str), \ - MTEXT_FORMAT_US_ASCII) - -extern MText *mtext__from_data (void *data, int nitems, - enum MTextFormat format, int need_copy); - -extern int mtext__replace (MText *mt, int from, int to, - char *from_str, char *to_str); - -extern int mtext__bol (MText *mt, int pos); - -extern int mtext__eol (MText *mt, int pos); - -#endif /* _M17N_MTEXT_H_ */ diff --git a/src/plist.c b/src/plist.c deleted file mode 100644 index b9854e8..0000000 --- a/src/plist.c +++ /dev/null @@ -1,1173 +0,0 @@ -/* plist.c -- plist module. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -/***en - @addtogroup m17nPlist - - @brief Property List objects and API for them. - - A @e property @e list (or @e plist for short) is a list of zero or - more properties. A property consists of a @e key and a @e value, - where key is a symbol and value is anything that can be cast to - (void *). - - If the key of a property is a @e managing @e key, its @e value is - a @e managed @e object. A property list itself is a managed - objects. */ - -/*=*/ - -#if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE) -/*** @addtogroup m17nInternal - @{ */ - -#include -#include - -#include "m17n.h" -#include "m17n-misc.h" -#include "internal.h" -#include "character.h" -#include "mtext.h" -#include "symbol.h" -#include "plist.h" - -static M17NObjectArray plist_table; - -/** Set PLIST to a newly allocated plist object. */ - -#define MPLIST_NEW(plist) \ - do { \ - M17N_OBJECT (plist, free_plist, MERROR_PLIST); \ - M17N_OBJECT_REGISTER (plist_table, plist); \ - } while (0) - - -/** Set the element of PLIST to KEY and VAL. If PLIST is an anchor, - append a new anchor. */ - -#define MPLIST_SET(plist, key, val) \ - do { \ - MPLIST_KEY (plist) = (key); \ - MPLIST_VAL (plist) = (val); \ - if (! (plist)->next) \ - MPLIST_NEW ((plist)->next); \ - } while (0) - - -/** Set the element of PLIST to KEY and VAL. PLIST must be an anchor. - Append a new anchor and set PLIST to that anchor. */ - -#define MPLIST_SET_ADVANCE(plist, key, val) \ - do { \ - MPLIST_KEY (plist) = (key); \ - MPLIST_VAL (plist) = (val); \ - MPLIST_NEW ((plist)->next); \ - plist = (plist)->next; \ - } while (0) - - -static void -free_plist (void *object) -{ - MPlist *plist = (MPlist *) object; - - do { - MPlist *next = plist->next; - - if (MPLIST_KEY (plist) != Mnil && MPLIST_KEY (plist)->managing_key) - M17N_OBJECT_UNREF (MPLIST_VAL (plist)); - M17N_OBJECT_UNREGISTER (plist_table, plist); - free (plist); - plist = next; - } while (plist && plist->control.ref_count == 1); - M17N_OBJECT_UNREF (plist); -} - - - -/* Load a plist from a string. */ - -#define READ_CHUNK 0x10000 - -typedef struct -{ - /* File pointer if the stream is associated with a file. Otherwise - NULL. */ - FILE *fp; - int eof; - unsigned char buffer[READ_CHUNK]; - unsigned char *p, *pend; -} MStream; - -static int -get_byte (MStream *st) -{ - int n; - - if (! st->fp || st->eof) - return EOF; - n = fread (st->buffer, 1, READ_CHUNK, st->fp); - if (n <= 0) - { - st->eof = 1; - return EOF; - } - st->p = st->buffer + 1; - st->pend = st->buffer + n; - return st->buffer[0]; -} - -#define GETC(st) \ - ((st)->p < (st)->pend ? *(st)->p++ : get_byte (st)) - - -#define UNGETC(c, st) \ - (*--(st)->p = (c)) - -/** Mapping table for reading a number. Hexadecimal chars - (0..9,A..F,a..F) are mapped to the corresponding numbers. - Apostrophe (code 39) is mapped to 254. All the other bytes are - mapped to 255. */ -unsigned char hex_mnemonic[256]; - -/** Mapping table for escaped characters. Mnemonic characters (e, b, - f, n, r, or t) that follows '\' are mapped to the corresponding - character code. All the other bytes are mapped to themselves. */ -unsigned char escape_mnemonic[256]; - - -/** Read an integer from the stream ST. It is assumed that we have - already read one character C. */ - -static int -read_decimal (MStream *st, int c) -{ - int num = 0; - - while (c >= '0' && c <= '9') - { - num = (num * 10) + (c - '0'); - c = GETC (st); - } - - if (c != EOF) - UNGETC (c, st); - return num; -} - -/** Read an unsigned from the stream ST. */ - -static unsigned -read_hexadesimal (MStream *st) -{ - int c; - unsigned num = 0, n; - - while ((c = GETC (st)) != EOF - && (n = hex_mnemonic[c]) < 16) - num = (num << 4) | n; - if (c != EOF) - UNGETC (c, st); - return num; -} - - -/** Read an M-text element from ST, and add it to LIST. Return a list - for the next element. */ - -static MPlist * -read_mtext_element (MPlist *plist, MStream *st) -{ - unsigned char buffer[1024]; - int bufsize = 1024; - unsigned char *buf = buffer; - int c, i; - - i = 0; - while ((c = GETC (st)) != EOF && c != '"') - { - if (i + MAX_UTF8_CHAR_BYTES >= bufsize) - { - bufsize *= 2; - if (buf == buffer) - { - MTABLE_MALLOC (buf, bufsize, MERROR_PLIST); - memcpy (buf, buffer, i); - } - else - MTABLE_REALLOC (buf, bufsize, MERROR_PLIST); - } - - if (c == '\\') - { - c = GETC (st); - if (c == EOF) - break; - if (c == 'x') - { - int next_c; - - c = read_hexadesimal (st); - next_c = GETC (st); - if (next_c != ' ') - UNGETC (next_c, st); - } - else - c = escape_mnemonic[c]; - } - - buf[i++] = c; - } - - MPLIST_SET_ADVANCE (plist, Mtext, - mtext__from_data (buf, i, MTEXT_FORMAT_UTF_8, 1)); - if (buf != buffer) - free (buf); - return plist; -} - -static int -read_character (MStream *st, int c) -{ - unsigned char buf[MAX_UTF8_CHAR_BYTES + 1]; - int len = CHAR_BYTES_BY_HEAD (c); - int i; - - buf[0] = c; - for (i = 1; i < len; i++) - { - c = GETC (st); - if (c == EOF - || (c & 0xC0) != 0x80) - break; - buf[i] = c; - } - if (i == len) - c = STRING_CHAR_UTF8 (buf); - else - c = buf[0]; - return c; -} - - -/** Read an integer element from ST, and add it to LIST. Return a - list for the next element. It is assumed that we have already - read the character C. */ - -static MPlist * -read_integer_element (MPlist *plist, MStream *st, int c) -{ - int num; - - if (c == '0' || c == '#') - { - c = GETC (st); - if (c == 'x') - num = read_hexadesimal (st); - else - num = read_decimal (st, c); - } - else if (c == '?') - { - c = GETC (st); - if (c == EOF) - num = 0; - else if (c != '\\') - { - if (c < 128 || ! CHAR_UNITS_BY_HEAD_UTF8 (c)) - num = c; - else - num = read_character (st, c); - } - else - { - c = GETC (st); - if (c == EOF) - num = '\\'; - else if (c < 128 || ! CHAR_UNITS_BY_HEAD_UTF8 (c)) - num = escape_mnemonic[c]; - else - num = read_character (st, c); - } - } - else if (c == '-') - num = - read_decimal (st, GETC (st)); - else - num = read_decimal (st, c); - - MPLIST_SET_ADVANCE (plist, Minteger, (void *) num); - return plist; -} - -/** Read a symbol element from ST, and add it to LIST. Return a list - for the next element. */ - -static MPlist * -read_symbol_element (MPlist *plist, MStream *st) -{ - unsigned char buffer[1024]; - int bufsize = 1024; - unsigned char *buf = buffer; - int c, i; - - i = 0; - while ((c = GETC (st)) != EOF - && c > ' ' - && c != ')' && c != '(' && c != '"') - { - if (i >= bufsize) - { - bufsize *= 2; - if (buf == buffer) - { - MTABLE_MALLOC (buf, bufsize, MERROR_PLIST); - memcpy (buf, buffer, i); - } - else - MTABLE_REALLOC (buf, bufsize, MERROR_PLIST); - } - if (c == '\\') - { - c = GETC (st); - if (c == EOF) - break; - c = escape_mnemonic[c]; - } - buf[i++] = c; - } - - buf[i] = 0; - MPLIST_SET_ADVANCE (plist, Msymbol, msymbol ((char *) buf)); - if (buf != buffer) - free (buf); - if (c > ' ') - UNGETC (c, st); - return plist; -} - -/* Read an element of various type from stream ST, and add it to LIST. - Return a list for the next element. The element type is decided by - the first token character found as below: - '(': plist - '"': mtext - '0'..'9', '-': integer - '?': integer representing character code - the other ASCII letters: symbol -*/ - -static MPlist * -read_element (MPlist *plist, MStream *st) -{ - int c; - - /* Skip separators and comments. */ - while (1) - { - while ((c = GETC (st)) != EOF && c <= ' '); - if (c != ';') - break; - while ((c = GETC (st)) != EOF && c != '\n'); - if (c == EOF) - break; - } - - if (c == '(') - { - MPlist *pl, *p; - - MPLIST_NEW (pl); - p = pl; - while ((p = read_element (p, st))); - MPLIST_SET_ADVANCE (plist, Mplist, pl); - return plist; - } - if (c == '"') - return read_mtext_element (plist, st); - if ((c >= '0' && c <= '9') || c == '-' || c == '?' || c == '#') - return read_integer_element (plist, st, c); - if (c == EOF || c == ')') - return NULL; - UNGETC (c, st); - return read_symbol_element (plist, st); -} - -void -write_element (MText *mt, MPlist *plist) -{ - if (MPLIST_SYMBOL_P (plist)) - { - MSymbol sym = MPLIST_SYMBOL (plist); - - if (sym == Mnil) - { - MTEXT_CAT_ASCII (mt, "nil"); - } - else - { - char *name = MSYMBOL_NAME (sym); - char *buf = alloca (MSYMBOL_NAMELEN (sym) * 2 + 1), *p = buf; - - while (*name) - { - if (*name <= ' ' || *name == '"' || *name == ')' || *name == ')') - *p++ = '\\'; - *p++ = *name++; - } - *p = '\0'; - MTEXT_CAT_ASCII (mt, buf); - } - } - else if (MPLIST_INTEGER_P (plist)) - { - int num = MPLIST_INTEGER (plist); - char buf[128]; - - sprintf (buf, "%d", num); - MTEXT_CAT_ASCII (mt, buf); - } - else if (MPLIST_PLIST_P (plist)) - { - MPlist *pl; - - plist = MPLIST_PLIST (plist); - mtext_cat_char (mt, '('); - MPLIST_DO (pl, plist) - { - if (pl != plist) - mtext_cat_char (mt, ' '); - write_element (mt, pl); - } - mtext_cat_char (mt, ')'); - } - else if (MPLIST_MTEXT_P (plist)) - { - mtext_cat_char (mt, '"'); - /* Not yet implemnted */ - mtext_cat_char (mt, '"'); - } -} - -/* Support functions for mdebug_dump_plist. */ - -static void -dump_string (char *str) -{ - char *p = str, *pend = p + strlen (p), *new, *p1; - - new = p1 = alloca ((pend - p) * 4 + 1); - while (p < pend) - { - if (*p < 0) - { - sprintf (p1, "\\x%02X", (unsigned char) *p); - p1 += 4; - } - else if (*p < ' ') - { - *p1++ = '^'; - *p1++ = *p + '@'; - } - else if (*p == ' ') - { - *p1++ = '\\'; - *p1++ = ' '; - } - else - *p1++ = *p; - p++; - } - *p1 = '\0'; - fprintf (stderr, "%s", new); -} - -static void -dump_plist_element (MPlist *plist, int indent) -{ - char *prefix = (char *) alloca (indent + 1); - MSymbol key; - - memset (prefix, 32, indent); - prefix[indent] = 0; - - key = MPLIST_KEY (plist); - fprintf (stderr, "(%s(#%d) ", msymbol_name (MPLIST_KEY (plist)), - plist->control.ref_count); - if (key == Msymbol) - dump_string (msymbol_name (MPLIST_SYMBOL (plist))); - else if (key == Mtext) - mdebug_dump_mtext (MPLIST_MTEXT (plist), indent, 0); - else if (key == Minteger) - fprintf (stderr, "%x", MPLIST_INTEGER (plist)); - else if (key == Mstring) - fprintf (stderr, "\"%s\"", MPLIST_STRING (plist)); - else if (key == Mplist) - { - fprintf (stderr, "\n%s", prefix); - mdebug_dump_plist (MPLIST_PLIST (plist), indent); - } - else - fprintf (stderr, "0x%X", (unsigned) MPLIST_VAL (plist)); - fprintf (stderr, ")"); -} - - -/* Internal API */ -int -mplist__init () -{ - int i; - - plist_table.count = 0; - - Minteger = msymbol ("integer"); - Mplist = msymbol_as_managing_key ("plist"); - Mtext = msymbol_as_managing_key ("mtext"); - - for (i = 0; i < 256; i++) - hex_mnemonic[i] = 255; - for (i = '0'; i <= '9'; i++) - hex_mnemonic[i] = i - '0'; - for (i = 'A'; i <= 'F'; i++) - hex_mnemonic[i] = i - 'A' + 10; - for (i = 'a'; i <= 'f'; i++) - hex_mnemonic[i] = i - 'a' + 10; - for (i = 0; i < 256; i++) - escape_mnemonic[i] = i; - escape_mnemonic['e'] = 27; - escape_mnemonic['b'] = '\b'; - escape_mnemonic['f'] = '\f'; - escape_mnemonic['n'] = '\n'; - escape_mnemonic['r'] = '\r'; - escape_mnemonic['t'] = '\t'; - escape_mnemonic['\\'] = '\\'; - - return 0; -} - -void -mplist__fini (void) -{ - mdebug__report_object ("Plist", &plist_table); -} - - -/* Parse this form of PLIST: - (symbol:KEY1 TYPE1:VAL1 symbol:KEY2 TYPE2:VAL2 ...) - and return a newly created plist of this form: - (KEY1:VAL1 KEY2:VAL2 ...) */ - -MPlist * -mplist__from_plist (MPlist *plist) -{ - MPlist *pl, *p; - - MPLIST_NEW (pl); - p = pl; - while (! MPLIST_TAIL_P (plist)) - { - MSymbol key, type; - - if (! MPLIST_SYMBOL_P (plist)) - MERROR (MERROR_PLIST, NULL); - key = MPLIST_SYMBOL (plist); - plist = MPLIST_NEXT (plist); - type = MPLIST_KEY (plist); - if (type->managing_key) - M17N_OBJECT_REF (MPLIST_VAL (plist)); - MPLIST_SET_ADVANCE (p, key, MPLIST_VAL (plist)); - plist = MPLIST_NEXT (plist); - } - return pl; -} - -/** Parse this form of PLIST: - ((symbol:KEY1 ANY:VAL1 ... ) (symbol:KEY2 ANY:VAL2 ...) ...) - and return a newly created plist of this form: - (KEY1:(ANY:VAL1 ...) KEY2:(ANY:VAL2 ...) ...) - ANY can be any type. */ - -MPlist * -mplist__from_alist (MPlist *plist) -{ - MPlist *pl, *p; - - MPLIST_NEW (pl); - p = pl; - MPLIST_DO (plist, plist) - { - MPlist *elt; - - if (! MPLIST_PLIST_P (plist)) - MERROR (MERROR_PLIST, NULL); - elt = MPLIST_PLIST (plist); - if (! MPLIST_SYMBOL_P (elt)) - MERROR (MERROR_PLIST, NULL); - MPLIST_SET_ADVANCE (p, MPLIST_SYMBOL (elt), MPLIST_NEXT (elt)); - M17N_OBJECT_REF (MPLIST_NEXT (elt)); - } - return pl; -} - - -MPlist * -mplist__from_file (FILE *fp) -{ - MPlist *plist, *pl; - MStream st; - - st.fp = fp; - st.eof = 0; - st.p = st.pend = st.buffer; - MPLIST_NEW (plist); - pl = plist; - while ((pl = read_element (pl, &st))); - return plist; -} - - -/** Parse $STR of $N bytes and return a property list object. $FORMAT - must be either @c MTEXT_FORMAT_US_ASCII or @c MTEXT_FORMAT_UTF_8, - and controls how to produce @c STRING or @c M-TEXT in the - following definition. - - The syntax of $STR is as follows. - - PLIST ::= '(' ELEMENT * ')' - - ELEMENT ::= SYMBOL | INTEGER | UNSIGNED | STRING | M-TEXT | PLIST - - SYMBOL ::= ascii-character-sequence - - INTEGER ::= '-' ? [ '0' | .. | '9' ] + - - UNSIGNED ::= '0x' [ '0' | .. | '9' | 'A' | .. | 'F' | 'a' | .. | 'f' ] + - - STRING ::= '"' byte-sequence '"' - - M-TEXT ::= '"' byte-sequence '"' - - Each kind of @c ELEMENT is assigned one of these keys: - @c Msymbol, @c Mint, @c Munsigned, - @c Mstring, @c Mtext, @c Mplist - - In an ascii-character-sequence, a backslush (\) is used as the escape - character, which means that, for instance, "abc\ def" - produces a symbol whose name is of length seven with the fourth - character being a space. - - In a byte-sequence, "\r", "\n", "\e", and "\t" are replaced by CR, - NL, ESC, and TAB character respectively, "\xXX" are replaced by - byte 0xXX. After this replacement, the byte-sequence is decoded - into STRING or M-TEXT as below: - - If $FORMAT is MTEXT_FORMAT_US_ASCII and the byte-sequence - contains only ASCII characters, it is decoded into STRING. - Otherwise, it is regarded as an UTF-8 sequence, and decoded into - M-TEXT. */ - -MPlist * -mplist__from_string (unsigned char *str, int n) -{ - MPlist *plist, *pl; - MStream st; - - st.fp = NULL; - st.eof = 0; - st.p = str; - st.pend = str + n; - MPLIST_NEW (plist); - pl = plist; - while ((pl = read_element (pl, &st))); - return plist; -} - -int -mplist__serialize (MText *mt, MPlist *plist) -{ - MPlist *pl; - - MPLIST_DO (pl, plist) - { - if (pl != plist) - mtext_cat_char (mt, ' '); - write_element (mt, pl); - } - return 0; -} - -MPlist * -mplist__deserialize (MText *mt) -{ - if (mt->format > MTEXT_FORMAT_UTF_8) - MERROR (MERROR_PLIST, NULL); - return mplist__from_string (MTEXT_DATA (mt), mtext_nbytes (mt)); -} - - -/*** @} */ -#endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */ - - -/* External API */ - -/*** @addtogroup m17nPlist */ -/*** @{ */ -/*=*/ - -/***en - @brief Symbol whose name is "integer". - - The symbol @c Minteger has the name "integer". A value - of a plist whose key is @c Minteger must be an integer. */ - -MSymbol Minteger; -/*=*/ - -/***en - @brief Symbol whose name is "plist". - - The symbol @c Mplist has the name "plist". It is a - managing key. A value of a plist whose key is @c Mplist must be a - plist. */ - -MSymbol Mplist; -/*=*/ - -/***en - @brief Symbol whose name is "mtext". - - The symbol @c Mtext has the name "mtext". It is a - managing key. A value of a plist whose key is @c Mtext must be an - M-text. */ - -/***ja - @brief "text" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë - - ÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë @c Mtext ¤Ï "text" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä´ÉÍý - ¥­¡¼¤Ç¤¢¤ë¡£ */ - -MSymbol Mtext; - - -/*=*/ -/***en - @brief Create a property list object. - - The mplist () function returns a newly created property list - object of length zero. - - @returns - This function returns a newly created property list. - - @errors - This function never fails. */ - -MPlist * -mplist () -{ - MPlist *plist; - - MPLIST_NEW (plist); - return plist; -} - -/*=*/ -/***en - @brief Copy a plist. - - The mplist_copy () function copies $PLIST. In the copy, the - values are the same as those of $PLIST. - - @return - This function returns a newly created plist which is a copy of - $PLIST. */ -/*** - @errors - This function never fails. */ - -MPlist * -mplist_copy (MPlist *plist) -{ - MPlist *copy = mplist (), *pl = copy; - - MPLIST_DO (plist, plist) - pl = mplist_add (pl, MPLIST_KEY (plist), MPLIST_VAL (plist)); - return copy; -} - -/*=*/ - -/***en - @brief Set the value of a property in a property list object. - - The mplist_put () function searches property list object $PLIST - from the beginning for a property whose key is $KEY. If such a - property is found, its value is changed to $VALUE. Otherwise, a - new property whose key is $KEY and value is $VALUE is appended at - the end of $PLIST. See the documentation of mplist_add () for - the restriction on $KEY and $VAL. - - If $KEY is a managing key, $VAL must be a managed object. In this - case, the reference count of the old value, if not @c NULL, is - decremented by one, and that of $VAL is incremented by one. - - @return - If the operation was successful, mplist_put () returns a sublist of - $PLIST whose first element is the just modified or added one. - Otherwise, it returns @c NULL. */ - -MPlist * -mplist_put (MPlist *plist, MSymbol key, void *val) -{ - if (key == Mnil) - MERROR (MERROR_PLIST, NULL); - MPLIST_FIND (plist, key); - if (key->managing_key) - { - if (! MPLIST_TAIL_P (plist)) - M17N_OBJECT_UNREF (MPLIST_VAL (plist)); - M17N_OBJECT_REF (val); - } - MPLIST_SET (plist, key, val); - return plist; -} - -/*=*/ - -/***en - @brief Get the value of a property in a property list object. - - The mplist_get () function searches property list object $PLIST - from the beginning for a property whose key is $KEY. If such a - property is found, a pointer to its value is returned as the type - of (void *). If not found, @c NULL is returned. - - When @c NULL is returned, there are two possibilities: one is the - case where no property is found (see above); the other is the case - where a property is found and its value is @c NULL. In case that - these two cases must be distinguished, use the mplist_find_by_key () - function. */ - -/*** - @seealso - mplist_find_by_key () */ - -void * -mplist_get (MPlist *plist, MSymbol key) -{ - MPLIST_FIND (plist, key); - return (MPLIST_TAIL_P (plist) ? NULL : MPLIST_VAL (plist)); -} - -/*=*/ - -/***en - @brief Add a property at the end of a property list object. - - The mplist_add () function appends at the end of $PLIST a property - whose key is $KEY and value is $VAL. $KEY can be any symbol - other than @c Mnil. - - If $KEY is a managing key, $VAL must be a managed object. In this - case, the reference count of $VAL is incremented by one. - - @return - If the operation was successful, mplist_add () returns a sublist of - $PLIST whose first element is the just added one. Otherwise, it - returns @c NULL. */ - -MPlist * -mplist_add (MPlist *plist, MSymbol key, void *val) -{ - if (key == Mnil) - MERROR (MERROR_PLIST, NULL); - MPLIST_FIND (plist, Mnil); - if (key->managing_key) - M17N_OBJECT_REF (val); - MPLIST_KEY (plist) = key; - MPLIST_VAL (plist) = val; - MPLIST_NEW (plist->next); - return plist; -} - -/*=*/ - -/***en - @brief Push a property to a property list object. - - The mplist_push () function pushes at the top of $PLIST a - property whose key is $KEY and value si $VAL. - - If $KEY is a managing key, $VAL must be a managed object. In this - case, the reference count of $VAL is incremented by one. - - @return - If the operation was successful, this function returns $PLIST. - Otherwise, it returns @c NULL. */ - -MPlist * -mplist_push (MPlist *plist, MSymbol key, void *val) -{ - MPlist *pl; - - if (key == Mnil) - MERROR (MERROR_PLIST, NULL); - MPLIST_NEW (pl); - MPLIST_KEY (pl) = MPLIST_KEY (plist); - MPLIST_VAL (pl) = MPLIST_VAL (plist); - pl->next = plist->next; - plist->next = pl; - if (key->managing_key) - M17N_OBJECT_REF (val); - MPLIST_KEY (plist) = key; - MPLIST_VAL (plist) = val; - return plist; -} - -/*=*/ - -/***en - @brief Pop a property from a property list object. - - The mplist_pop () function pops the topmost property from $PLIST. - As a result, the key and value of $PLIST becomes those of the next - of $PLIST. - - @return - If the operation was successful, this function return the value of - the just popped property. Otherwise, it returns @c NULL. */ - -void * -mplist_pop (MPlist *plist) -{ - void *val; - MPlist *next; - - if (MPLIST_TAIL_P (plist)) - return NULL; - val = MPLIST_VAL (plist); - next = plist->next; - MPLIST_KEY (plist) = MPLIST_KEY (next); - MPLIST_VAL (plist) = MPLIST_VAL (next); - if (MPLIST_KEY (plist) != Mnil - && MPLIST_KEY (plist)->managing_key - && MPLIST_VAL (plist)) - M17N_OBJECT_REF (MPLIST_VAL (plist)); - plist->next = next->next; - if (plist->next) - M17N_OBJECT_REF (plist->next); - M17N_OBJECT_UNREF (next); - return val; -} - -/*=*/ -/***en - @brief Find a property of a specific key in a property list object. - - The mplist_find_by_key () function searches property list object - $PLIST from the beginning for a property whose key is $KEY. If - such a property is found, a sublist of $PLIST whose first element - is the found one is returned. Otherwise, @c NULL is returned. - - If $KEY is Mnil, it returns the last a sublist of $PLIST whose - first element is the last one of $PLIST. */ - -MPlist * -mplist_find_by_key (MPlist *plist, MSymbol key) -{ - MPLIST_FIND (plist, key); - return (MPLIST_TAIL_P (plist) - ? (key == Mnil ? plist : NULL) - : plist); -} - -/*=*/ -/***en - @brief Find a property of a specific value in a property list object. - - The mplist_find_by_value () function searches property list object - $PLIST from the beginning for a property whose value is $VAL. If - such a property is found, a sublist of $PLIST whose first element - is the found one is returned. Otherwise, @c NULL is returned. */ - -MPlist * -mplist_find_by_value (MPlist *plist, void *val) -{ - MPLIST_DO (plist, plist) - { - if (MPLIST_VAL (plist) == val) - return plist; - } - return NULL; -} - -/*=*/ - -/***en - @brief Return the next sublist of a plist. - - The mplist_next () function returns a pointer to the sublist of - $PLIST, which begins at the second element in $PLIST. If the - length of $PLIST is zero, it returns @c NULL. */ - -MPlist * -mplist_next (MPlist *plist) -{ - return (MPLIST_TAIL_P (plist) ? NULL : plist->next); -} - -/*=*/ - -/***en - @brief Set the first property in a property list object. - - The mplist_set () function sets the key and value of the first - property in property list object $PLIST to $KEY and $VALUE, - respectively. See the documentation of mplist_add () for the - restriction on $KEY and $VAL. - - @return - If the operation was successful, mplist_set () returns $PLIST. - Otherwise, it returns @c NULL. */ - -MPlist * -mplist_set (MPlist *plist, MSymbol key, void * val) -{ - if (key == Mnil) - { - if (! MPLIST_TAIL_P (plist)) - { - key = MPLIST_KEY (plist); - M17N_OBJECT_UNREF (MPLIST_NEXT (plist)); - MPLIST_KEY (plist) = Mnil; - if (key->managing_key && MPLIST_VAL (plist)) - M17N_OBJECT_UNREF (MPLIST_VAL (plist)); - plist->next = NULL; - } - } - else - { - if (! MPLIST_TAIL_P (plist) - && MPLIST_KEY (plist)->managing_key - && MPLIST_VAL (plist)) - M17N_OBJECT_UNREF (MPLIST_VAL (plist)); - if (key->managing_key) - M17N_OBJECT_REF (val); - MPLIST_SET (plist, key, val); - } - return plist; -} - -/*=*/ - -/***en - @brief Return the length of a plist. - - The mplist_length () function returns the number of properties in - property list object $PLIST. */ - -int -mplist_length (MPlist *plist) -{ - int n; - - for (n = 0; ! (MPLIST_TAIL_P (plist)); n++, plist = plist->next); - return n; -} - -/*=*/ - -/***en - @brief Return the key of the first property in a property list object. - - The mplist_key () function returns the key of the first property - in property list object $PLIST. If the length of $PLIST is zero, - it returns @c Mnil. */ - -MSymbol -mplist_key (MPlist *plist) -{ - return MPLIST_KEY (plist); -} - -/*=*/ - -/***en - @brief Return the value of the first property in a property list object. - - The mplist_value () function returns the value of the first - property in property list object $PLIST. If the length of $PLIST - is zero, it returns @c NULL. */ - -void * -mplist_value (MPlist *plist) -{ - return MPLIST_VAL (plist); -} - -/*** @} */ - -/*** @addtogroup m17nDebug */ -/*=*/ -/*** @{ */ - -/***en - @brief Dump a plist. - - The mdebug_dump_plist () function prints $PLIST in a human - readable way to the stderr. $INDENT specifies how many columns to - indent the lines but the first one. - - @return - This function returns $PLIST. */ - -MPlist * -mdebug_dump_plist (MPlist *plist, int indent) -{ - char *prefix = (char *) alloca (indent + 1); - MPlist *pl; - int first = 1; - - memset (prefix, 32, indent); - prefix[indent] = 0; - - fprintf (stderr, "("); - MPLIST_DO (pl, plist) - { - if (first) - first = 0; - else - fprintf (stderr, "\n%s ", prefix); - dump_plist_element (pl, indent + 2); - } - fprintf (stderr, ")"); - return plist; -} - -/*** @} */ - -/* - Local Variables: - coding: euc-japan - End: -*/ diff --git a/src/plist.h b/src/plist.h deleted file mode 100644 index 372a3e6..0000000 --- a/src/plist.h +++ /dev/null @@ -1,97 +0,0 @@ -/* plist.h -- header file for the plist module. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -#ifndef _M17N_PLIST_H_ -#define _M17N_PLIST_H_ - -struct MPlist -{ - /** Header for a managed object. */ - M17NObject control; - - /**en Key of the first element of the plist. If the value is Mnil, - this is the tail of the plist. In that case, and is - NULL. If the value is a managing key, is a managed - object. */ - MSymbol key; - - /**en Value of the first element of the plist. */ - void *val; - - /**en Plist for the next element. */ - MPlist *next; -}; - -/** Macros to access each member of PLIST. */ - -#define MPLIST_KEY(plist) ((plist)->key) -#define MPLIST_VAL(plist) ((plist)->val) -#define MPLIST_VAL_MANAGED_P(plist) ((plist)->control.flag) -#define MPLIST_NEXT(plist) ((plist)->next) -#define MPLIST_TAIL_P(plist) ((plist)->key == Mnil) - -#define MPLIST_SYMBOL_P(plist) (MPLIST_KEY (plist) == Msymbol) -#define MPLIST_STRING_P(plist) (MPLIST_KEY (plist) == Mstring) -#define MPLIST_MTEXT_P(plist) (MPLIST_KEY (plist) == Mtext) -#define MPLIST_INTEGER_P(plist) (MPLIST_KEY (plist) == Minteger) -#define MPLIST_PLIST_P(plist) (MPLIST_KEY (plist) == Mplist) - -#define MPLIST_SYMBOL(plist) ((MSymbol) MPLIST_VAL (plist)) -#define MPLIST_STRING(plist) ((char *) MPLIST_VAL (plist)) -#define MPLIST_MTEXT(plist) ((MText *) MPLIST_VAL (plist)) -#define MPLIST_INTEGER(plist) ((int) MPLIST_VAL (plist)) -#define MPLIST_PLIST(plist) ((MPlist *) MPLIST_VAL (plist)) - -#define MPLIST_FIND(plist, key) \ - do { \ - while (! MPLIST_TAIL_P (plist) && MPLIST_KEY (plist) != (key)) \ - (plist) = (plist)->next; \ - } while (0) - - -#define MPLIST_DO(elt, plist) \ - for ((elt) = (plist); ! MPLIST_TAIL_P (elt); (elt) = MPLIST_NEXT (elt)) - -#define MPLIST_LENGTH(plist) \ - (MPLIST_TAIL_P (plist) ? 0 \ - : MPLIST_TAIL_P ((plist)->next) ? 1 \ - : MPLIST_TAIL_P ((plist)->next->next) ? 2 \ - : mplist_length (plist)) - - -extern unsigned char hex_mnemonic[256]; -extern unsigned char escape_mnemonic[256]; - -extern MPlist *mplist__from_file (FILE *fp); - -extern MPlist *mplist__from_plist (MPlist *plist); - -extern MPlist *mplist__from_alist (MPlist *plist); - -extern MPlist *mplist__from_string (unsigned char *str, int n); - -extern int mplist__serialize (MText *mt, MPlist *plist); - -extern MPlist *mplist__deserialize (MText *mt); - - -#endif /* _M17N_PLIST_H_ */ diff --git a/src/symbol.c b/src/symbol.c deleted file mode 100644 index f85db6c..0000000 --- a/src/symbol.c +++ /dev/null @@ -1,698 +0,0 @@ -/* symbol.c -- symbol module. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -/***en - @addtogroup m17nSymbol - - @brief Symbol objects and API for them. - - The m17n library uses objects called @e symbols as unambiguous - identifiers. Symbols are similar to atoms in the X library, but a - symbol can have zero or more @e symbol @e properties. A symbol - property consists of a @e key and a @e value, where key is also a - symbol and value is anything that can be cast to (void - *). "The symbol property that belongs to the symbol S and - whose key is K" may be shortened to "K property of S". - - Symbols are used mainly in the following three ways. - - @li As keys of symbol properties and other properties. - - @li To represent various objects, e.g. charsets, coding systems, - fontsets. - - @li As arguments of the m17n library functions to control - their behavior. - - There is a special kind of symbol, a @e managing @e key. The - value of a property whose key is a managing key must be a @e - managed @e object. See @ref m17nObject for the detail. -*/ - -/***ja - @addtogroup m17nSymbol ¥·¥ó¥Ü¥ë - - @brief ¥·¥ó¥Ü¥ë¥ª¥Ö¥¸¥§¥¯¥È¤È¤½¤ì¤Ë´Ø¤¹¤ë API - - m17n ¥é¥¤¥Ö¥é¥ê¤Ï°ì°Õ¤Ë·è¤Þ¤ëµ­½Ò»Ò¤È¤·¤Æ @e ¥·¥ó¥Ü¥ë ¤È¸Æ¤Ö¥ª¥Ö¥¸¥§ - ¥¯¥È¤òÍѤ¤¤ë¡£¥·¥ó¥Ü¥ë¤Ï X ¥é¥¤¥Ö¥é¥ê¤Î¥¢¥È¥à¤È»÷¤Æ¤¤¤ë¤¬¡¢0 ¸Ä°Ê - ¾å¤Î @e ¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£ ¤ò»ý¤Ä¤³¤È¤¬¤Ç¤­¤ëÅÀ¤Ç¡¢¥¢¥È¥à¤è¤ê¹âµ¡ - ǽ¤Ç¤¢¤ë¡£¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤Ï @e ¥­¡¼ ¤È @e ÃÍ ¤«¤é¤Ê¤ë¡£¥­¡¼¤Ï¤½ - ¤ì¼«ÂÎ¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢ÃÍ¤Ï (void *) ·¿¤Ë¥­¥ã¥¹¥È¤Ç¤­¤ë¤â - ¤Î¤Ê¤é²¿¤Ç¤â¤è¤¤¡£¡Ö¥·¥ó¥Ü¥ë S ¤¬»ý¤Ä¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¥­¡¼ - ¤¬ K ¤Î¤â¤Î¡×¤ò´Êñ¤Ë¡ÖS ¤Î K ¥×¥í¥Ñ¥Æ¥£¡×¤È¸Æ¤Ö¤³¤È¤¬¤¢¤ë¡£ - - ¥·¥ó¥Ü¥ë¤ÎÍÑÅӤϼç¤Ë°Ê²¼¤Î3Ä̤ê¤Ç¤¢¤ë¡£ - - @li ¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£ (¤ª¤è¤Ó¾¤Î¥×¥í¥Ñ¥Æ¥£) ¤Î¥­¡¼¤òɽ¤ï¤¹¡£ - - @li ʸ»ú¥»¥Ã¥È¡¢¥³¡¼¥É·Ï¡¢¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ê¤É¤Î³Æ¼ï¥ª¥Ö¥¸¥§¥¯¥È¤òɽ - ¤ï¤¹¡£ - - @li m17n ¥é¥¤¥Ö¥é¥ê´Ø¿ô¤Î°ú¿ô¤È¤Ê¤ê¡¢´Ø¿ô¤ÎµóÆ°¤òÀ©¸æ¤¹¤ë¡£ - - ¥­¡¼¤¬ @c Mmanaging_key ¤ÇÃͤ¬ @c NULL °Ê³°¤Î¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ò - »ý¤Ä¥·¥ó¥Ü¥ë¤Ï¡¢@e ´ÉÍý¥­¡¼ ¤È¸Æ¤Ð¤ì¤ë¡£¤¢¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼ - ¤¬´ÉÍý¥­¡¼¤Î¾ì¹ç¡¢¤½¤ÎÃÍ¤Ï @e ´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È ¤È¤·¤Æ°·¤ï¤ì¤ë¡£ - ´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È¤Ë´Ø¤¹¤ë¾ÜºÙ¤Ï @e ´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È ¤Î¾Ï¤ò»²¾È - ¤Î¤³¤È¡£ - - ¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤Ë¤ÏÃͤÎÂå¤ê¤Ë @e ¥×¥í¥Ð¥¤¥À´Ø¿ô ¤ò»ý¤¿¤»¤ë¤³¤È - ¤â¤Ç¤­¤ë¡£¥×¥í¥Ð¥¤¥À´Ø¿ô¤Ï¤½¤Î¥­¡¼¤ÎÃͤòÆÀ¤è¤¦¤È¤¹¤ë»þ¤Ë¸Æ¤Ð¤ì¡¢¤½ - ¤ÎÊÖ¤êÃͤ¬µá¤á¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ÎÃͤȤʤ롣¤³¤Î»ÅÁȤߤˤè¤Ã¤Æ¥· - ¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ÎÃÙ±äɾ²Á¤¬²Äǽ¤Ë¤Ê¤ë¡£¥×¥í¥Ð¥¤¥À´Ø¿ô¤ÏÃͤòÊÖ¤¹¤È - Ʊ»þ¤ËÃͤòÀßÄꤹ¤ë¤³¤È¤â¤Ç¤­¡¢¤³¤Î¾ì¹ç¤Ë¤Ï¡¢¥×¥í¥Ð¥¤¥À´Ø¿ô¼«ÂΤÏÃÍ - ¤ÎÀßÄê°Ê¹ß¤Ï̵¸ú¤È¤Ê¤ë¡£ */ - -/*=*/ - -#if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE) -/*** @addtogroup m17nInternal - @{ */ - -#include -#include -#include -#include - -#include "m17n.h" -#include "m17n-misc.h" -#include "internal.h" -#include "symbol.h" -#include "character.h" -#include "mtext.h" -#include "plist.h" - -static int num_symbols; - -#define SYMBOL_TABLE_SIZE 1024 - -static MSymbol symbol_table[SYMBOL_TABLE_SIZE]; - -static unsigned -hash_string (const char *str, int len) -{ - unsigned hash = 0; - const char *end = str + len; - unsigned c; - - while (str < end) - { - c = *((unsigned char *) str++); - if (c >= 0140) - c -= 40; - hash = ((hash << 3) + (hash >> 28) + c); - } - return hash & (SYMBOL_TABLE_SIZE - 1); -} - - -static MPlist * -serialize_symbol (void *val) -{ - MPlist *plist = mplist (); - - mplist_add (plist, Msymbol, val); - return plist; -} - -static void * -deserialize_symbol (MPlist *plist) -{ - return (MPLIST_SYMBOL_P (plist) ? MPLIST_SYMBOL (plist) : Mnil); -} - - -/* Internal API */ - -int -msymbol__init () -{ - num_symbols = 0; - Mnil = (MSymbol) 0; - Mt = msymbol ("t"); - Msymbol = msymbol ("symbol"); - Mstring = msymbol ("string"); - return 0; -} - -void -msymbol__fini () -{ - int i; - MSymbol sym, next; - - for (i = 0; i < SYMBOL_TABLE_SIZE; i++) - for (sym = symbol_table[i]; sym; sym = sym->next) - if (! MPLIST_TAIL_P (&sym->plist)) - { - if (sym->plist.key->managing_key) - M17N_OBJECT_UNREF (sym->plist.val); - M17N_OBJECT_UNREF (sym->plist.next); - } - for (i = 0; i < SYMBOL_TABLE_SIZE; i++) - for (sym = symbol_table[i]; sym; sym = next) - { - next = sym->next; - free (sym->name); - free (sym); - } -} - - -MSymbol -msymbol__with_len (const char *name, int len) -{ - char *p = alloca (len + 1); - - memcpy (p, name, len); - p[len] = '\0'; - return msymbol (p); -} - - -/** Canonicalize the name of SYM, and return a symbol of the - canonicalized name. Canonicalization is done by this rule: - o convert all uppercase characters to lowercase. - o remove all non alpha-numeric characters. - o change the leading "ibm" to "cp". - o change the leading "cp" to "ibm" - o remove the leading "iso". - For instance: - "ISO-8859-2" -> "88592" - "euc-JP" -> "eucjp" - "IBM851" -> "cp851" - "CP1250" -> "ibm1250" - - This function is used to canonicalize charset and coding system - names. */ - -MSymbol -msymbol__canonicalize (MSymbol sym) -{ - char *name = sym->name; - /* Extra 2 bytes are for changing "cpXXX" to "ibmXXX" and - terminating '\0'. */ - char *canon = (char *) alloca (strlen (name) + 2); - char *p = canon; - - for (; *name; name++) - if (ISALNUM (*name)) - *p++ = TOLOWER (*name); - *p = '\0'; - if (p - canon > 3 && canon[0] == 'i') - { - if (canon[1] == 'b' && canon[2] == 'm' && isdigit (canon[3])) - { - /* Change "ibmXXX" to "cpXXX". */ - canon++; - canon[0] = 'c'; - canon[1] = 'p'; - } - else if (canon[1] == 's' && canon[2] == 'o') - { - /* Change "isoXXX" to "XXX". */ - canon += 3; - } - } - else if (p - canon > 2 - && canon[0] == 'c' && canon[1] == 'p' && isdigit (canon[2])) - { - /* Change "cpXXX" to "ibmXXX". */ - for (; p >= canon + 2; p--) - p[1] = p[0]; - canon[0] = 'i'; - canon[1] = 'b'; - canon[2] = 'm'; - } - - return msymbol (canon); -} - -MTextPropSerializeFunc msymbol__serializer = serialize_symbol; -MTextPropDeserializeFunc msymbol__deserializer = deserialize_symbol; - -/*** @} */ -#endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */ - - -/* External API */ - -/*** @addtogroup m17nSymbol */ -/*** @{ */ - -/*=*/ -/***en - @brief Symbol whose name is "nil". - - The symbol #Mnil has the name "nil" and, in general, - represents @e false or @e no. When coerced to "int", its value is - zero. #Mnil can't have any symbol property. */ - -/***ja - @brief ÄêµÁºÑ¥·¥ó¥Ü¥ë Mnil - - ¥·¥ó¥Ü¥ë #Mnil ¤Ï "nil" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢°ìÈ̤ˡֵ¶¡× - ¤ò°ÕÌ£¤¹¤ë¡£#Mnil ¼«¿È¤Ï¤¤¤«¤Ê¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤â»ý¤¿¤Ê¤¤¡£ */ - -MSymbol Mnil; - -/*=*/ - -/***en - @brief Symbol whose name is "t". - - The symbol #Mt has the name "t" and, in general, - represents @e true or @e yes. */ - -/***ja - @brief ÄêµÁºÑ¥·¥ó¥Ü¥ë Mt - - ¥·¥ó¥Ü¥ë #Mt ¤Ï "t" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢°ìÈ̤ˡֿ¿¡×¤ò°Õ - Ì£¤¹¤ë¡£ */ - -MSymbol Mt; - -/*=*/ - -/***en - @brief Symbol whose name is "string". - - The symbol #Mstring has the name "string" and is used - as an argument of the functions mchar_define_property (), - etc. */ - -/***ja - @brief "string" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë - - ÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë #Mstring ¤Ï "string" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢ - ´Ø¿ô mchar_define_property () Åù¤Î°ú¿ô¤È¤·¤Æ»È¤ï¤ì¤ë¡£ */ - -MSymbol Mstring; - -/*=*/ - -/***en - @brief Symbol whose name is "symbol". - - The symbol #Msymbol has the name "symbol" and is used - as an argument of the functions mchar_define_property (), - etc. */ - -/***ja - @brief "symbol" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë - - ÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë #Msymbol ¤Ï "symbol" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢ - ´Ø¿ô mchar_define_property () Åù¤Î°ú¿ô¤È¤·¤Æ»È¤ï¤ì¤ë¡£ */ - -MSymbol Msymbol; - -/*=*/ - -/***en - @brief Get a symbol. - - The msymbol () function returns the canonical symbol whose name is - $NAME. If there is none, one is created. The created one is not - a managing key. - - Symbols whose name starts by two spaces are reserved by the m17n - library, and are used by the library only internally. - - @return - This function returns the found or created symbol. - - @errors - This function never fails. */ - -/***ja - @brief »ØÄꤵ¤ì¤¿Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤òÊÖ¤¹ - - ´Ø¿ô msymbol () ¤Ï $NAME ¤È¤¤¤¦Ì¾Á°¤Î¥·¥ó¥Ü¥ë¤òÊÖ¤¹¡£¤½¤Î¤è¤¦¤Ê¥· - ¥ó¥Ü¥ë¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç¤Ë¤Ï¡¢¿·¤·¤¤¥·¥ó¥Ü¥ë¤¬¼«Æ°Åª¤Ëºî¤é¤ì¤ë¡£ - - @latexonly \IPAlabel{msymbol} @endlatexonly */ - -/*** - @seealso - msymbol_as_managing_key (), msymbol_name (), msymbol_exist () */ - -MSymbol -msymbol (const char *name) -{ - MSymbol sym; - int len; - unsigned hash; - - len = strlen (name); - if (len == 3 && name[0] == 'n' && name[1] == 'i' && name[2] == 'l') - return Mnil; - hash = hash_string (name, len); - len++; - for (sym = symbol_table[hash]; sym; sym = sym->next) - if (len == sym->length - && *name == *(sym->name) - && ! memcmp (name, sym->name, len)) - return sym; - - num_symbols++; - MTABLE_CALLOC (sym, 1, MERROR_SYMBOL); - MTABLE_MALLOC (sym->name, len, MERROR_SYMBOL); - memcpy (sym->name, name, len); - sym->length = len; - sym->next = symbol_table[hash]; - symbol_table[hash] = sym; - return sym; -} - -/***en - @brief Create a managing key. - - The msymbol_as_managing_key () function returns a newly created - managing key whose name is $NAME. It there already exists a - symbol of name $NAME, it returns #Mnil. - - Symbols whose name starts by two spaces are reserved by the m17n - library, and are used by the library only internally. - - @return - If the operation was successful, this function returns the created - symbol. Otherwise, it returns #Mnil. */ - -/*** - @errors - MERROR_SYMBOL - - @seealso - msymbol (), msymbol_exist () */ - -MSymbol -msymbol_as_managing_key (const char *name) -{ - MSymbol sym; - int len; - unsigned hash; - - len = strlen (name); - if (len == 3 && name[0] == 'n' && name[1] == 'i' && name[2] == 'l') - MERROR (MERROR_SYMBOL, Mnil); - hash = hash_string (name, len); - len++; - for (sym = symbol_table[hash]; sym; sym = sym->next) - if (len == sym->length - && *name == *(sym->name) - && ! memcmp (name, sym->name, len)) - MERROR (MERROR_SYMBOL, Mnil); - - num_symbols++; - MTABLE_CALLOC (sym, 1, MERROR_SYMBOL); - sym->managing_key = 1; - MTABLE_MALLOC (sym->name, len, MERROR_SYMBOL); - memcpy (sym->name, name, len); - sym->length = len; - sym->next = symbol_table[hash]; - symbol_table[hash] = sym; - return sym; -} - -/*=*/ - -/***en - @brief Search for a symbol that has a specified name. - - The msymbol_exist () function searches for the symbol whose name - is $NAME. - - @return - If such a symbol exists, msymbol_exist () returns that symbol. - Otherwise it returns the predefined symbol #Mnil. - - @errors - This function never fails. */ - -/***ja - @brief »ØÄꤵ¤ì¤¿Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤òõ¤¹ - - ´Ø¿ô msymbol_exist () ¤Ï $NAME ¤È¤¤¤¦Ì¾Á°¤Î¥·¥ó¥Ü¥ë¤òõ¤¹¡£ - - @return - ¤â¤·¤½¤Î¤è¤¦¤Ê¥·¥ó¥Ü¥ë¤¬Â¸ºß¤¹¤ë¤Ê¤é¤Ð¤½¤Î¥·¥ó¥Ü¥ë¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê - ¤±¤ì¤Ð¡¢ÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë #Mnil ¤òÊÖ¤¹¡£ */ - -/***@seealso - msymbol_name (), msymbol () */ - -MSymbol -msymbol_exist (const char *name) -{ - MSymbol sym; - int len; - unsigned hash; - - len = strlen (name); - if (len == 3 && name[0] == 'n' && name[1] == 'i' && name[2] == 'l') - return Mnil; - hash = hash_string (name, len); - len++; - for (sym = symbol_table[hash]; sym; sym = sym->next) - if (len == sym->length - && *name == *(sym->name) - && ! memcmp (name, sym->name, len)) - return sym; - return Mnil; -} - -/*=*/ - -/***en - @brief Get symbol name. - - The msymbol_name () function returns a pointer to a string - containing the name of $SYMBOL. - - @return - Name of the specified symbol. - - @errors - This function never fails. */ -/***ja - @brief ¥·¥ó¥Ü¥ë¤Î̾Á°¤òÊÖ¤¹ - - ´Ø¿ô msymbol_name () ¤Ï»ØÄꤵ¤ì¤¿¥·¥ó¥Ü¥ë $SYMBOL ¤Î̾Á°¤òÊÖ¤¹¡£ */ - -/***@seealso - msymbol (), msymbol_exist () */ - -char * -msymbol_name (MSymbol symbol) -{ - return (symbol == Mnil ? "nil" : symbol->name); -} - -/*=*/ -/***en - @brief Set the value of a symbol property. - - The msymbol_put () function assigns $VAL to the value of the - symbol property that belongs to $SYMBOL and whose key is $KEY. If - the symbol property already has a value, $VAL overwrites the old - one. Both $SYMBOL and $KEY must not be #Mnil. - - If $KEY is a managing key, $VAL must be a managed object. In this - case, the reference count of the old value, if not @c NULL, is - decremented by one, and that of $VAL is incremented by one. - - @return - If the operation was successful, msymbol_put () returns 0. - Otherwise it returns -1 and assigns an error code to the external - variable #merror_code. */ - -/***ja - @brief ¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ËÃͤòÀßÄꤹ¤ë - - ´Ø¿ô msymbol_put () ¤Ï¡¢¥·¥ó¥Ü¥ë $SYMBOL Ãæ¤Ç¥­¡¼¤¬ $KEY ¤Ç¤¢¤ë¥· - ¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ÎÃͤò $VAL ¤ËÀßÄꤹ¤ë¡£¤½¤Î¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤Ë¤¹ - ¤Ç¤ËÃͤ¬¤¢¤ì¤Ð¾å½ñ¤­¤¹¤ë¡£$SYMBOL, $KEY ¤È¤â´û¤ËÀ¸À®¤µ¤ì¤¿¥·¥ó¥Ü - ¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ - - @return - ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¡¢msymbol_put () ¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤ò - ÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ */ - -/*** - @errors - @c MERROR_SYMBOL - - @seealso - msymbol_get () */ - -int -msymbol_put (MSymbol symbol, MSymbol key, void *val) -{ - if (symbol == Mnil || key == Mnil) - MERROR (MERROR_SYMBOL, -1); - mplist_put (&symbol->plist, key, val); - return 0; -} - -/*=*/ - -/***en - @brief Get the value of a symbol property. - - The msymbol_get () function searches for the value of the symbol - property that belongs to $SYMBOL and whose key is $KEY. If - $SYMBOL has such a symbol property, its value is returned. - Otherwise @c NULL is returned. - - - @return - If an error is detected, msymbol_get () returns @c NULL and - assigns an error code to the external variable #merror_code. */ - -/***ja - @brief ¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòõ¤¹ - - ´Ø¿ô msymbol_get () ¤Ï¡¢¥·¥ó¥Ü¥ë $SYMBOL ¤¬»ý¤Ä¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£ - ¤Î¤¦¤Á¡¢¥­¡¼¤¬ $KEY ¤Ç¤¢¤ë¤â¤Î¤òõ¤¹¡£¤â¤·³ºÅö¤¹¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£ - ¤¬Â¸ºß¤¹¤ì¤Ð¡¢¤½¤ì¤ÎÃͤòÊÖ¤¹¡£¤â¤·³ºÅö¤¹¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤¬Â¸ºß - ¤»¤º¡¢¤«¤Ä $KEY ¤ËÂФ¹¤ë¥×¥í¥Ð¥¤¥À´Ø¿ô¤¬Â¸ºß¤¹¤ì¤Ð¡¢¤½¤Î´Ø¿ô¤ò¸Æ¤ó - ¤Ç¤½¤ÎÌá¤êÃͤòÊÖ¤¹¡£³ºÅö¤¹¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤â¥×¥í¥Ð¥¤¥À´Ø¿ô¤â¸ - ºß¤·¤Ê¤¤¾ì¹ç¤Ï³°ÉôÊÑ¿ô #merror_code ¤òÊѤ¨¤º¤Ë @c NULL ¤òÊÖ¤¹¡£ - - ¥¨¥é¡¼¤¬¸¡½Ð¤µ¤ì¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô - #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ */ - -/*** - @errors - @c MERROR_SYMBOL - - @seealso - msymbol_put () */ - -void * -msymbol_get (MSymbol symbol, MSymbol key) -{ - MPlist *plist; - - if (symbol == Mnil || key == Mnil) - return NULL; - plist = &symbol->plist; - MPLIST_FIND (plist, key); - return (MPLIST_TAIL_P (plist) ? NULL : MPLIST_VAL (plist)); -} - -/*** @} */ - -#include - -/*** @addtogroup m17nDebug */ -/*=*/ -/*** @{ */ - -/***en - @brief Dump a symbol. - - The mdebug_dump_symbol () function prints $SYMBOL in a human - readable way to the stderr. $INDENT specifies how many columns to - indent the lines but the first one. - - @return - This function returns $SYMBOL. - - @errors - MERROR_DEBUG */ - -MSymbol -mdebug_dump_symbol (MSymbol symbol, int indent) -{ - char *prefix; - MPlist *plist; - char *name; - - if (indent < 0) - MERROR (MERROR_DEBUG, Mnil); - prefix = (char *) alloca (indent + 1); - memset (prefix, 32, indent); - prefix[indent] = 0; - - if (symbol == Mnil) - plist = NULL, name = "nil"; - else - plist = &symbol->plist, name = symbol->name; - - fprintf (stderr, "%s%s", prefix, name); - while (plist && MPLIST_KEY (plist) != Mnil) - { - fprintf (stderr, ":%s", MPLIST_KEY (plist)->name); - plist = MPLIST_NEXT (plist); - } - return symbol; -} - -/***en - @brief Dump all symbol names. - - The mdebug_dump_all_symbols () function prints names of all - symbols to the stderr. $INDENT specifies how many columns to - indent the lines but the first one. - - @return - This function returns #Mnil. - - @errors - MERROR_DEBUG */ - - -MSymbol -mdebug_dump_all_symbols (int indent) -{ - char *prefix; - int i; - MSymbol sym; - - if (indent < 0) - MERROR (MERROR_DEBUG, Mnil); - prefix = (char *) alloca (indent + 1); - memset (prefix, 32, indent); - prefix[indent] = 0; - - fprintf (stderr, "(symbol-list"); - for (i = 0; i < SYMBOL_TABLE_SIZE; i++) - if ((sym = symbol_table[i])) - { - fprintf (stderr, "\n%s (%4d", prefix, i); - for (; sym; sym = sym->next) - fprintf (stderr, " '%s'", sym->name); - fprintf (stderr, ")"); - } - fprintf (stderr, ")"); - return Mnil; -} - -/*** @} */ - -/* - Local Variables: - coding: euc-japan - End: -*/ diff --git a/src/symbol.h b/src/symbol.h deleted file mode 100644 index 24238d9..0000000 --- a/src/symbol.h +++ /dev/null @@ -1,56 +0,0 @@ -/* symbol.h -- header file for the symbol module. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -#ifndef _M17N_SYMBOL_H_ -#define _M17N_SYMBOL_H_ - -#include "plist.h" - -struct MSymbol -{ - /** 1 iff a value of property (including text-property) whose key is - the symbol is a managed object. */ - unsigned managing_key : 1; - - /* Name of the symbol. */ - char *name; - - /* Byte length of . */ - int length; - - /* Plist of the symbol. */ - MPlist plist; - - MSymbol next; -}; - -#define MSYMBOL_NAME(sym) ((sym)->name) -#define MSYMBOL_NAMELEN(sym) ((sym)->length - 1) - -extern MSymbol msymbol__with_len (const char *name, int len); - -extern MSymbol msymbol__canonicalize (MSymbol sym); - -extern MTextPropSerializeFunc msymbol__serializer; -extern MTextPropDeserializeFunc msymbol__deserializer; - -#endif /* _M17N_SYMBOL_H_ */ diff --git a/src/textprop.c b/src/textprop.c deleted file mode 100644 index 4f8a45f..0000000 --- a/src/textprop.c +++ /dev/null @@ -1,2855 +0,0 @@ -/* textprop.c -- text property module. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -/***en - @addtogroup m17nTextProperty - @brief Function to handle text properties. - - Each character in an M-text can have properties called @e text @e - properties. Text properties store various kinds of information - attached to parts of an M-text to provide application programs - with a unified view of those information. As rich information can - be stored in M-texts in the form of text properties, functions in - application programs can be simple. - - A text property consists of a @e key and @e values, where key is a - symbol and values are anything that can be cast to (void - *). Unlike other types of properties, a text property can - have multiple values. "The text property whose key is K" may be - shortened to "K property". */ - -/***ja - @addtogroup m17nTextProperty - @brief ¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤òÁàºî¤¹¤ë¤¿¤á¤Î´Ø¿ô - - M-text Æâ¤Î³Æʸ»ú¤Ï¡¢@e ¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£ ¤È¸Æ¤Ð¤ì¤ë¥×¥í¥Ñ¥Æ¥£¤ò - »ý¤Ä¤³¤È¤¬¤Ç¤­¤ë¡£¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Ë¤è¤Ã¤Æ¡¢¥Æ¥­¥¹¥È¤Î³ÆÉô°Ì¤Ë´Ø - ¤¹¤ëÍÍ¡¹¤Ê¾ðÊó¤ò M-text Æâ¤ËÊÝ»ý¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¡£¤½¤Î¤¿¤á¡¢¤½¤ì¤é - ¤Î¾ðÊó¤ò¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥àÆâ¤ÇÅý°ìŪ¤Ë°·¤¦¤³¤È¤¬¤Ç¤­¤ë¡£¤Þ - ¤¿¡¢M-text ¼«ÂΤ¬Ë­É٤ʾðÊó¤ò»ý¤Ä¤¿¤á¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à - Ãæ¤Î³Æ´Ø¿ô¤ò´ÊÁDz½¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¡£ - - ¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Ï @e ¥­¡¼ ¤È @e ÃÍ ¤«¤é¤Ê¤ë¡£¥­¡¼¤Ï¥·¥ó¥Ü¥ë¤Ç¤¢ - ¤ê¡¢ÃÍ¤Ï (void *) ·¿¤Ë¥­¥ã¥¹¥È¤Ç¤­¤ë¤â¤Î¤Ê¤é²¿¤Ç¤â¤è¤¤¡£ - ¾¤Î¥¿¥¤¥×¤Î¥×¥í¥Ñ¥Æ¥£¤È°Û¤Ê¤ê¡¢Æ±°ì¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ÏÊ£¿ô¤ÎÃÍ - ¤ò»ý¤Ä¤³¤È¤¬µö¤µ¤ì¤ë¡£¡Ö@c Mxxx ¤È¤¤¤¦¥­¡¼¤ò»ý¤Ä¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¡× - ¤Î¤³¤È¤ò´Êñ¤Ë¡Öxxx ¥×¥í¥Ñ¥Æ¥£¡×¤È¸Æ¤Ö¤³¤È¤¬¤¢¤ë¡£ */ - -/*=*/ - -#if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE) -/*** @addtogroup m17nInternal - @{ */ - -#include -#include -#include -#include - -#ifdef HAVE_XML2 -#include -#include -#include -#include -#endif - -#include "m17n.h" -#include "m17n-misc.h" -#include "internal.h" -#include "symbol.h" -#include "mtext.h" -#include "textprop.h" - -#define TEXT_PROP_DEBUG - -#undef xassert -#ifdef TEXT_PROP_DEBUG -#define xassert(X) do {if (!(X)) mdebug_hook ();} while (0) -#else -#define xassert(X) (void) 0 -#endif /* not FONTSET_DEBUG */ - -/* Hierarchy of objects (MText, MTextPlist, MInterval, MTextProperty) - -MText - | key/a key/b key/x - +--> MTextPlist -> MTextPlist -> ... -> MTextPlist - | | - | +- tail <-----------------------------------------+ - | | | - | +- head <--> MInterval <--> ... <--> MInterval <--+ - | - +- tail --------------------------------------------------------+ - | | - +- head --> MInterval <--> MInterval <--> ... <--> MInterval <--+ - | | - +---------------+------------> MTextProperty - +--> MTextProperty - ... - - -Examples: - -MTextProperty a/A [AAAAAAAAAAAAAAAAAAAAA] -MTextProperty a/B [BBBBBBBBBBBBBBBBB] -MTextPlist a |--intvl1--|-intvl2-|-intvl3-|---intvl4---|-intvl5-| - - -MTextProperty b/A [AAAAAAAAAA] -MTextProperty b/B [BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB] -MTextPlist b |-intvl1-|--intvl2--|--intvl3--|-intvl4-|--intvl5--| - - M-text |--------------------------------------------------| - - (intvl == MInterval) - -*/ - -/* The structure MTextProperty is defined in textprop.h. */ - -/** MInterval is the structure for an interval that holds text - properties of the same key in a specific range of M-text. - All intervals are stored in MIntervalPool. */ - -typedef struct MInterval MInterval; - -struct MInterval -{ - /** Stack of pointers to text properties. If the interval does not - have any text properties, this member is NULL or contains random - values. */ - MTextProperty **stack; - - /** How many values are in . */ - int nprops; - - /** Length of . */ - int stack_length; - - /** Start and end character positions of the interval. If is - negative, this interval is not in use. */ - int start, end; - - /** Pointers to the previous and next intervals. If is 0, - is NULL and this interval is pointed by MTextPlist->head. - If is the size of the M-text, is NULL, and this - interval is pointed by MTextPlist->tail. */ - MInterval *prev, *next; -}; - -/** MTextPlist is a structure to hold text properties of an M-text by - chain. Each element in the chain is for a specific key. */ - -typedef struct MTextPlist MTextPlist; - -struct MTextPlist -{ - /** Key of the property. */ - MSymbol key; - - /** The head and tail intervals. ->start is always 0. - end is always MText->nchars. */ - MInterval *head, *tail; - - /** Lastly accessed interval. */ - MInterval *cache; - - /* Not yet implemented. */ - int (*modification_hook) (MText *mt, MSymbol key, int from, int to); - - /** Pointer to the next property in the chain, or NULL if the - property is the last one in the chain. */ - MTextPlist *next; -}; - - -/** How many intervals one interval-pool can contain. */ - -#define INTERVAL_POOL_SIZE 1024 - -typedef struct MIntervalPool MIntervalPool; - - -/** MIntervalPool is the structure for an interval-pool which store - intervals. Each interval-pool contains INTERVAL_POOL_SIZE number - of intervals, and is chained from the root #interval_pool. */ - -struct MIntervalPool -{ - /** Array of intervals. */ - MInterval intervals[INTERVAL_POOL_SIZE]; - - /** The smallest index to an unused interval. */ - int free_slot; - - /** Pointer to the next interval-pool. */ - MIntervalPool *next; -}; - - -/** Root of interval-pools. */ - -static MIntervalPool interval_pool_root; - -/* For debugging. */ - -static M17NObjectArray text_property_table; - -/** Return a newly allocated interval pool. */ - -static MIntervalPool * -new_interval_pool () -{ - MIntervalPool *pool; - int i; - - MSTRUCT_CALLOC (pool, MERROR_TEXTPROP); - for (i = 0; i < INTERVAL_POOL_SIZE; i++) - pool->intervals[i].end = -1; - pool->free_slot = 0; - pool->next = NULL; - return pool; -} - - -/** Return a new interval for the region START and END. */ - -static MInterval * -new_interval (int start, int end) -{ - MIntervalPool *pool; - MInterval *interval; - - for (pool = &interval_pool_root; - pool->free_slot >= INTERVAL_POOL_SIZE; - pool = pool->next) - { - if (! pool->next) - pool->next = new_interval_pool (); - } - - interval = &(pool->intervals[pool->free_slot]); - interval->stack = NULL; - interval->nprops = 0; - interval->stack_length = 0; - interval->prev = interval->next = NULL; - interval->start = start; - interval->end = end; - - pool->free_slot++; - while (pool->free_slot < INTERVAL_POOL_SIZE - && pool->intervals[pool->free_slot].end >= 0) - pool->free_slot++; - - return interval; -} - - -/** Free INTERVAL and return INTERVAL->next. It assumes that INTERVAL - has no properties. */ - -static MInterval * -free_interval (MInterval *interval) -{ - MIntervalPool *pool = &interval_pool_root; - int i; - - xassert (interval->nprops == 0); - if (interval->stack) - free (interval->stack); - while ((interval < pool->intervals - || interval >= pool->intervals + INTERVAL_POOL_SIZE) - && pool->next) - pool = pool->next; - - i = interval - pool->intervals; - interval->end = -1; - if (i < pool->free_slot) - pool->free_slot = i; - return interval->next; -} - - -/** If necessary, allocate a stack for INTERVAL so that it can contain - NUM number of text properties. */ - -#define PREPARE_INTERVAL_STACK(interval, num) \ - do { \ - if ((num) > (interval)->stack_length) \ - { \ - MTABLE_REALLOC ((interval)->stack, (num), MERROR_TEXTPROP); \ - (interval)->stack_length = (num); \ - } \ - } while (0) - - -/** Return a copy of INTERVAL. The copy still shares text properties - with INTERVAL. If MASK_BITS is not zero, don't copy such text - properties whose control flags contains bits in MASK_BITS. */ - -static MInterval * -copy_interval (MInterval *interval, int mask_bits) -{ - MInterval *new = new_interval (interval->start, interval->end); - int nprops = interval->nprops; - MTextProperty **props = alloca (sizeof (MTextProperty *) * nprops); - int i, n; - - for (i = n = 0; i < nprops; i++) - if (! (interval->stack[i]->control.flag & mask_bits)) - props[n++] = interval->stack[i]; - new->nprops = n; - if (n > 0) - { - PREPARE_INTERVAL_STACK (new, n); - memcpy (new->stack, props, sizeof (MTextProperty *) * n); - } - - return new; -} - - -/** Free text property OBJECT. */ - -static void -free_text_property (void *object) -{ - MTextProperty *prop = (MTextProperty *) object; - - if (prop->key->managing_key) - M17N_OBJECT_UNREF (prop->val); - M17N_OBJECT_UNREGISTER (text_property_table, prop); - free (object); -} - - -/** Return a newly allocated text property whose key is KEY and value - is VAL. */ - -static MTextProperty * -new_text_property (MText *mt, int from, int to, MSymbol key, void *val, - int control_bits) -{ - MTextProperty *prop; - - M17N_OBJECT (prop, free_text_property, MERROR_TEXTPROP); - prop->control.flag = control_bits; - prop->attach_count = 0; - prop->mt = mt; - prop->start = from; - prop->end = to; - prop->key = key; - prop->val = val; - if (key->managing_key) - M17N_OBJECT_REF (val); - M17N_OBJECT_REGISTER (text_property_table, prop); - return prop; -} - - -/** Return a newly allocated copy of text property PROP. */ - -#define COPY_TEXT_PROPERTY(prop) \ - new_text_property ((prop)->mt, (prop)->start, (prop)->end, \ - (prop)->key, (prop)->val, (prop)->control.flag) - - -/** Split text property PROP at position INTERVAL->start, and make all - the following intervals contain the copy of PROP instead of PROP. - It assumes that PROP starts before INTERVAL. */ - -static void -split_property (MTextProperty *prop, MInterval *interval) -{ - int end = prop->end; - MTextProperty *copy; - int i; - - prop->end = interval->start; - copy = COPY_TEXT_PROPERTY (prop); - copy->start = interval->start; - copy->end = end; - /* Check all stacks of the following intervals, and if it contains - PROP, change it to the copy of it. */ - for (; interval && interval->start < end; interval = interval->next) - for (i = 0; i < interval->nprops; i++) - if (interval->stack[i] == prop) - { - interval->stack[i] = copy; - M17N_OBJECT_REF (copy); - copy->attach_count++; - prop->attach_count--; - M17N_OBJECT_UNREF (prop); - } - M17N_OBJECT_UNREF (copy); -} - -/** Divide INTERVAL of PLIST at POS if POS is in between the range of - INTERVAL. */ - -static void -divide_interval (MTextPlist *plist, MInterval *interval, int pos) -{ - MInterval *new; - int i; - - if (pos == interval->start || pos == interval->end) - return; - new = copy_interval (interval, 0); - interval->end = new->start = pos; - new->prev = interval; - new->next = interval->next; - interval->next = new; - if (new->next) - new->next->prev = new; - if (plist->tail == interval) - plist->tail = new; - for (i = 0; i < new->nprops; i++) - { - new->stack[i]->attach_count++; - M17N_OBJECT_REF (new->stack[i]); - } -} - - -/** Check if INTERVAL of PLIST can be merged with INTERVAL->next. If - mergeable, extend INTERVAL to the end of INTEVAL->next, free - INTERVAL->next, and return INTERVAL. Otherwise, return - INTERVAL->next. */ - -static MInterval * -maybe_merge_interval (MTextPlist *plist, MInterval *interval) -{ - int nprops = interval->nprops; - MInterval *next = interval->next; - int i, j; - - if (! next || nprops != next->nprops) - return next; - - for (i = 0; i < nprops; i++) - { - MTextProperty *prop = interval->stack[i]; - MTextProperty *old = next->stack[i]; - - if (prop != old - && (prop->val != old->val - || prop->end != old->start - || prop->control.flag & MTEXTPROP_NO_MERGE - || old->control.flag & MTEXTPROP_NO_MERGE)) - return interval->next; - } - - - for (i = 0; i < nprops; i++) - { - MTextProperty *prop = interval->stack[i]; - MTextProperty *old = next->stack[i]; - - if (prop != old) - { - MInterval *tail; - - for (tail = next->next; tail && tail->start < old->end; - tail = tail->next) - for (j = 0; j < tail->nprops; j++) - if (tail->stack[j] == old) - { - old->attach_count--; - xassert (old->attach_count); - tail->stack[j] = prop; - prop->attach_count++; - M17N_OBJECT_REF (prop); - } - xassert (old->attach_count == 1); - old->mt = NULL; - prop->end = old->end; - } - old->attach_count--; - M17N_OBJECT_UNREF (old); - } - - interval->end = next->end; - interval->next = next->next; - if (next->next) - next->next->prev = interval; - if (plist->tail == next) - plist->tail = interval; - plist->cache = interval; - next->nprops = 0; - free_interval (next); - return interval; -} - - -/*** Adjust start and end positions of intervals between HEAD and TAIL - (both inclusive) by diff. Adjust also start and end positions - of text properties belonging to those intervals. */ - -static void -adjust_intervals (MInterval *head, MInterval *tail, int diff) -{ - int i; - MTextProperty *prop; - - if (diff < 0) - { - /* Adjust end poistions of properties starting before HEAD. */ - for (i = 0; i < head->nprops; i++) - { - prop = head->stack[i]; - if (prop->start < head->start) - prop->end += diff; - } - - /* Adjust start and end positions of properties starting at - HEAD, and adjust HEAD itself. */ - while (1) - { - for (i = 0; i < head->nprops; i++) - { - prop = head->stack[i]; - if (prop->start == head->start) - prop->start += diff, prop->end += diff; - } - head->start += diff; - head->end += diff; - if (head == tail) - break; - head = head->next; - } - } - else - { - /* Adjust start poistions of properties ending after TAIL. */ - for (i = 0; i < tail->nprops; i++) - { - prop = tail->stack[i]; - if (prop->end > tail->end) - prop->start += diff; - } - - /* Adjust start and end positions of properties ending at - TAIL, and adjust TAIL itself. */ - while (1) - { - for (i = 0; i < tail->nprops; i++) - { - prop = tail->stack[i]; - if (prop->end == tail->end) - prop->start += diff, prop->end += diff; - } - tail->start += diff; - tail->end += diff; - if (tail == head) - break; - tail = tail->prev; - } - } -} - -/* Return an interval of PLIST that covers the position POS. */ - -static MInterval * -find_interval (MTextPlist *plist, int pos) -{ - MInterval *interval; - MInterval *highest; - - if (pos < plist->head->end) - return plist->head; - if (pos >= plist->tail->start) - return (pos < plist->tail->end ? plist->tail : NULL); - - interval = plist->cache; - - if (pos < interval->start) - highest = interval->prev, interval = plist->head->next; - else if (pos < interval->end) - return interval; - else - highest = plist->tail->prev, interval = interval->next; - - if (pos - interval->start < highest->end - pos) - { - while (interval->end <= pos) - /* Here, we are sure that POS is not included in PLIST->tail, - thus, INTERVAL->next always points a valid next - interval. */ - interval = interval->next; - } - else - { - while (highest->start > pos) - highest = highest->prev; - interval = highest; - } - plist->cache = interval; - return interval; -} - -/* Push text property PROP on the stack of INTERVAL. */ - -#define PUSH_PROP(interval, prop) \ - do { \ - int n = (interval)->nprops; \ - \ - PREPARE_INTERVAL_STACK ((interval), n + 1); \ - (interval)->stack[n] = (prop); \ - (interval)->nprops += 1; \ - (prop)->attach_count++; \ - M17N_OBJECT_REF (prop); \ - if ((prop)->start > (interval)->start) \ - (prop)->start = (interval)->start; \ - if ((prop)->end < (interval)->end) \ - (prop)->end = (interval)->end; \ - } while (0) - - -/* Pop the topmost text property of INTERVAL from the stack. If it - ends after INTERVAL->end, split it. */ - -#define POP_PROP(interval) \ - do { \ - MTextProperty *prop; \ - \ - (interval)->nprops--; \ - prop = (interval)->stack[(interval)->nprops]; \ - xassert (prop->control.ref_count > 0); \ - xassert (prop->attach_count > 0); \ - if (prop->start < (interval)->start) \ - { \ - if (prop->end > (interval)->end) \ - split_property (prop, (interval)->next); \ - prop->end = (interval)->start; \ - } \ - else if (prop->end > (interval)->end) \ - prop->start = (interval)->end; \ - prop->attach_count--; \ - if (! prop->attach_count) \ - prop->mt = NULL; \ - M17N_OBJECT_UNREF (prop); \ - } while (0) - - -#define REMOVE_PROP(interval, prop) \ - do { \ - int i; \ - \ - for (i = (interval)->nprops - 1; i >= 0; i--) \ - if ((interval)->stack[i] == (prop)) \ - break; \ - if (i < 0) \ - break; \ - (interval)->nprops--; \ - for (; i < (interval)->nprops; i++) \ - (interval)->stack[i] = (interval)->stack[i + 1]; \ - (prop)->attach_count--; \ - if (! (prop)->attach_count) \ - (prop)->mt = NULL; \ - M17N_OBJECT_UNREF (prop); \ - } while (0) - - -#ifdef TEXT_PROP_DEBUG -static int -check_plist (MTextPlist *plist, int start) -{ - MInterval *interval = plist->head; - MInterval *cache = plist->cache; - int cache_found = 0; - - if (interval->start != start - || interval->start >= interval->end) - return mdebug_hook (); - while (interval) - { - int i; - - if (interval == interval->next) - return mdebug_hook (); - - if (interval == cache) - cache_found = 1; - - if (interval->start >= interval->end) - return mdebug_hook (); - if ((interval->next - ? (interval->end != interval->next->start - || interval != interval->next->prev) - : interval != plist->tail)) - return mdebug_hook (); - for (i = 0; i < interval->nprops; i++) - { - if (interval->stack[i]->start > interval->start - || interval->stack[i]->end < interval->end) - return mdebug_hook (); - - if (! interval->stack[i]->attach_count) - return mdebug_hook (); - if (! interval->stack[i]->mt) - return mdebug_hook (); - if (interval->stack[i]->start == interval->start) - { - MTextProperty *prop = interval->stack[i]; - int count = prop->attach_count - 1; - MInterval *interval2; - - for (interval2 = interval->next; - interval2 && interval2->start < prop->end; - count--, interval2 = interval2->next) - if (count == 0) - return mdebug_hook (); - } - - if (interval->stack[i]->end > interval->end) - { - MTextProperty *prop = interval->stack[i]; - MInterval *interval2; - int j; - - for (interval2 = interval->next; - interval2 && interval2->start < prop->end; - interval2 = interval2->next) - { - for (j = 0; j < interval2->nprops; j++) - if (interval2->stack[j] == prop) - break; - if (j == interval2->nprops) - return mdebug_hook (); - } - } - if (interval->stack[i]->start < interval->start) - { - MTextProperty *prop = interval->stack[i]; - MInterval *interval2; - int j; - - for (interval2 = interval->prev; - interval2 && interval2->end > prop->start; - interval2 = interval2->prev) - { - for (j = 0; j < interval2->nprops; j++) - if (interval2->stack[j] == prop) - break; - if (j == interval2->nprops) - return mdebug_hook (); - } - } - } - interval = interval->next; - } - if (! cache_found) - return mdebug_hook (); - if (plist->head->prev || plist->tail->next) - return mdebug_hook (); - return 0; -} -#endif - - -/** Return a copy of plist that contains intervals between FROM and TO - of PLIST. The copy goes to the position POS of M-text MT. */ - -static MTextPlist * -copy_single_property (MTextPlist *plist, int from, int to, MText *mt, int pos) -{ - MTextPlist *new; - MInterval *interval1, *interval2; - MTextProperty *prop; - int diff = pos - from; - int i, j; - int mask_bits = MTEXTPROP_VOLATILE_STRONG | MTEXTPROP_VOLATILE_WEAK; - - MSTRUCT_CALLOC (new, MERROR_TEXTPROP); - new->key = plist->key; - new->next = NULL; - - interval1 = find_interval (plist, from); - new->head = copy_interval (interval1, mask_bits); - for (interval1 = interval1->next, interval2 = new->head; - interval1 && interval1->start < to; - interval1 = interval1->next, interval2 = interval2->next) - { - interval2->next = copy_interval (interval1, mask_bits); - interval2->next->prev = interval2; - } - new->tail = interval2; - new->head->start = from; - new->tail->end = to; - for (interval1 = new->head; interval1; interval1 = interval1->next) - for (i = 0; i < interval1->nprops; i++) - if (interval1->start == interval1->stack[i]->start - || interval1 == new->head) - { - prop = interval1->stack[i]; - interval1->stack[i] = COPY_TEXT_PROPERTY (prop); - interval1->stack[i]->mt = mt; - interval1->stack[i]->attach_count++; - if (interval1->stack[i]->start < from) - interval1->stack[i]->start = from; - if (interval1->stack[i]->end > to) - interval1->stack[i]->end = to; - for (interval2 = interval1->next; interval2; - interval2 = interval2->next) - for (j = 0; j < interval2->nprops; j++) - if (interval2->stack[j] == prop) - { - interval2->stack[j] = interval1->stack[i]; - interval1->stack[i]->attach_count++; - M17N_OBJECT_REF (interval1->stack[i]); - } - } - adjust_intervals (new->head, new->tail, diff); - new->cache = new->head; - for (interval1 = new->head; interval1 && interval1->next; - interval1 = maybe_merge_interval (new, interval1)); - xassert (check_plist (new, pos) == 0); - if (new->head == new->tail - && new->head->nprops == 0) - { - free_interval (new->head); - free (new); - new = NULL; - } - - return new; -} - -/** Return a newly allocated plist whose key is KEY on M-text MT. */ - -static MTextPlist * -new_plist (MText *mt, MSymbol key) -{ - MTextPlist *plist; - - MSTRUCT_MALLOC (plist, MERROR_TEXTPROP); - plist->key = key; - plist->head = new_interval (0, mtext_nchars (mt)); - plist->tail = plist->head; - plist->cache = plist->head; - plist->next = mt->plist; - mt->plist = plist; - return plist; -} - -/* Free PLIST and return PLIST->next. */ - -static MTextPlist * -free_textplist (MTextPlist *plist) -{ - MTextPlist *next = plist->next; - MInterval *interval = plist->head; - - while (interval) - { - while (interval->nprops > 0) - POP_PROP (interval); - interval = free_interval (interval); - } - free (plist); - return next; -} - -/** Return a plist that contains the property KEY of M-text MT. If - such a plist does not exist and CREATE is nonzero, create a new - plist and return it. */ - -static MTextPlist * -get_plist_create (MText *mt, MSymbol key, int create) -{ - MTextPlist *plist; - - plist = mt->plist; - while (plist && plist->key != key) - plist = plist->next; - - /* If MT does not have PROP, make one. */ - if (! plist && create) - plist = new_plist (mt, key); - return plist; -} - -/* Detach PROP. INTERVAL (if not NULL) contains PROP. */ - -static void -detach_property (MTextPlist *plist, MTextProperty *prop, MInterval *interval) -{ - MInterval *head; - int to = prop->end; - - xassert (prop->mt); - xassert (plist); - - M17N_OBJECT_REF (prop); - if (interval) - while (interval->start > prop->start) - interval = interval->prev; - else - interval = find_interval (plist, prop->start); - head = interval; - while (1) - { - REMOVE_PROP (interval, prop); - if (interval->end == to) - break; - interval = interval->next; - } - xassert (prop->attach_count == 0 && prop->mt == NULL); - M17N_OBJECT_UNREF (prop); - - while (head && head->end <= to) - head = maybe_merge_interval (plist, head); - xassert (check_plist (plist, 0) == 0); -} - -/* Delete text properties of PLIST between FROM and TO. MASK_BITS - specifies what kind of properties to delete. If DELETING is - nonzero, delete such properties too that are completely included in - the region. - - If the resulting PLIST still has any text properties, return 1, - else return 0. */ - -static int -delete_properties (MTextPlist *plist, int from, int to, - int mask_bits, int deleting) -{ - MInterval *interval; - int modified = 0; - int modified_from = from; - int modified_to = to; - int i; - - retry: - for (interval = find_interval (plist, from); - interval && interval->start < to; - interval = interval->next) - for (i = 0; i < interval->nprops; i++) - { - MTextProperty *prop = interval->stack[i]; - - if (prop->control.flag & mask_bits) - { - if (prop->start < modified_from) - modified_from = prop->start; - if (prop->end > modified_to) - modified_to = prop->end; - detach_property (plist, prop, interval); - modified++; - goto retry; - } - else if (deleting && prop->start >= from && prop->end <= to) - { - detach_property (plist, prop, interval); - modified++; - goto retry; - } - } - - if (modified) - { - interval = find_interval (plist, modified_from); - while (interval && interval->start < modified_to) - interval = maybe_merge_interval (plist, interval); - } - - return (plist->head != plist->tail || plist->head->nprops > 0); -} - -static void -pop_interval_properties (MInterval *interval) -{ - while (interval->nprops > 0) - POP_PROP (interval); -} - - -MInterval * -pop_all_properties (MTextPlist *plist, int from, int to) -{ - MInterval *interval; - - /* Be sure to have interval boundary at TO. */ - interval = find_interval (plist, to); - if (interval && interval->start < to) - divide_interval (plist, interval, to); - - /* Be sure to have interval boundary at FROM. */ - interval = find_interval (plist, from); - if (interval->start < from) - { - divide_interval (plist, interval, from); - interval = interval->next; - } - - pop_interval_properties (interval); - while (interval->end < to) - { - MInterval *next = interval->next; - - pop_interval_properties (next); - interval->end = next->end; - interval->next = next->next; - if (interval->next) - interval->next->prev = interval; - if (next == plist->tail) - plist->tail = interval; - if (plist->cache == next) - plist->cache = interval; - free_interval (next); - } - return interval; -} - - -/* Delete volatile text properties between FROM and TO. If KEY is - Mnil, we are going to delete text, thus both strongly and weakly - volatile properties must be deleted. Otherwise we are going to - modify a text property KEY, thus only strongly volatile properties - whose key is not KEY must be deleted. */ - -static void -prepare_to_modify (MText *mt, int from, int to, MSymbol key) -{ - MTextPlist *plist = mt->plist, *prev = NULL; - int mask_bits = MTEXTPROP_VOLATILE_STRONG; - int deleting = (key == Mnil) && (from < to); - - if (key == Mnil) - mask_bits |= MTEXTPROP_VOLATILE_WEAK; - while (plist) - { - if (plist->key != key - && ! delete_properties (plist, from, to, mask_bits, deleting)) - { - if (prev) - plist = prev->next = free_textplist (plist); - else - plist = mt->plist = free_textplist (plist); - } - else - prev = plist, plist = plist->next; - } -} - -void -extract_text_properties (MText *mt, int from, int to, MSymbol key, - MPlist *plist) -{ - MPlist *top; - MTextPlist *list = get_plist_create (mt, key, 0); - MInterval *interval; - - if (! list) - return; - interval = find_interval (list, from); - if (interval->nprops == 0 - && interval->start <= from && interval->end >= to) - return; - top = plist; - while (interval && interval->start < to) - { - if (interval->nprops == 0) - top = mplist_find_by_key (top, Mnil); - else - { - MPlist *current = top, *place; - int i; - - for (i = 0; i < interval->nprops; i++) - { - MTextProperty *prop = interval->stack[i]; - - place = mplist_find_by_value (current, prop); - if (place) - current = MPLIST_NEXT (place); - else - { - place = mplist_find_by_value (top, prop); - if (place) - { - mplist_pop (place); - if (MPLIST_NEXT (place) == MPLIST_NEXT (current)) - current = place; - } - mplist_push (current, Mt, prop); - current = MPLIST_NEXT (current); - } - } - } - interval = interval->next; - } - return; -} - -#define XML_TEMPLATE "\n\ -\n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - ]>\n\ -\n\ -" - - -/* for debugging... */ -#include - -void -dump_interval (MInterval *interval, int indent) -{ - char *prefix = (char *) alloca (indent + 1); - int i; - - memset (prefix, 32, indent); - prefix[indent] = 0; - - fprintf (stderr, "(interval %d-%d (%d)", interval->start, interval->end, - interval->nprops); - for (i = 0; i < interval->nprops; i++) - fprintf (stderr, "\n%s (%d %d/%d %d-%d 0x%x)", - prefix, i, - interval->stack[i]->control.ref_count, - interval->stack[i]->attach_count, - interval->stack[i]->start, interval->stack[i]->end, - (unsigned) interval->stack[i]->val); - fprintf (stderr, ")"); -} - -void -dump_textplist (MTextPlist *plist, int indent) -{ - char *prefix = (char *) alloca (indent + 1); - - memset (prefix, 32, indent); - prefix[indent] = 0; - - fprintf (stderr, "(properties"); - if (! plist) - fprintf (stderr, ")\n"); - else - { - fprintf (stderr, "\n"); - while (plist) - { - MInterval *interval = plist->head; - - fprintf (stderr, "%s (%s", prefix, msymbol_name (plist->key)); - while (interval) - { - fprintf (stderr, " (%d %d", interval->start, interval->end); - if (interval->nprops > 0) - { - int i; - - for (i = 0; i < interval->nprops; i++) - fprintf (stderr, " 0x%x", (int) interval->stack[i]->val); - } - fprintf (stderr, ")"); - interval = interval->next; - } - fprintf (stderr, ")\n"); - xassert (check_plist (plist, 0) == 0); - plist = plist->next; - } - } -} - - -/* Internal API */ - -int -mtext__prop_init () -{ - text_property_table.count = 0; - Mtext_prop_serializer = msymbol ("text-prop-serializer"); - Mtext_prop_deserializer = msymbol ("text-prop-deserializer"); - return 0; -} - -void -mtext__prop_fini () -{ - MIntervalPool *pool = interval_pool_root.next; - - while (pool) - { - MIntervalPool *next = pool->next; - free (pool); - pool = next; - } - interval_pool_root.next = NULL; - mdebug__report_object ("Text property", &text_property_table); -} - - -/** Free all plists. */ - -void -mtext__free_plist (MText *mt){ - - MTextPlist *plist = mt->plist; - - while (plist) - plist = free_textplist (plist); - mt->plist = NULL; -} - - -/** Extract intervals between FROM and TO of all properties (except - for volatile ones) in PLIST, and make a new plist from them for - M-text MT. */ - -MTextPlist * -mtext__copy_plist (MTextPlist *plist, int from, int to, MText *mt, int pos) -{ - MTextPlist *copy, *this; - - if (from == to) - return NULL; - for (copy = NULL; plist && ! copy; plist = plist->next) - copy = copy_single_property (plist, from, to, mt, pos); - if (! plist) - return copy; - for (; plist; plist = plist->next) - if ((this = copy_single_property (plist, from, to, mt, pos))) - { - this->next = copy; - copy = this; - } - - return copy; -} - -void -mtext__adjust_plist_for_delete (MText *mt, int pos, int len) -{ - MTextPlist *plist; - int to; - - if (len == 0 || pos == mt->nchars) - return; - if (len == mt->nchars) - { - mtext__free_plist (mt); - return; - } - - to = pos + len; - prepare_to_modify (mt, pos, to, Mnil); - for (plist = mt->plist; plist; plist = plist->next) - { - MInterval *interval = pop_all_properties (plist, pos, to); - MInterval *prev = interval->prev, *next = interval->next; - - if (prev) - prev->next = next; - else - plist->head = next; - if (next) - { - adjust_intervals (next, plist->tail, -len); - next->prev = prev; - } - else - plist->tail = prev; - if (prev && next) - next = maybe_merge_interval (plist, prev); - plist->cache = next ? next : prev; - free_interval (interval); - xassert (check_plist (plist, 0) == 0); - } -} - -void -mtext__adjust_plist_for_insert (MText *mt, int pos, int nchars, - MTextPlist *plist) -{ - MTextPlist *pl, *pl_last, *pl2, *p; - int i; - MInterval *interval; - - if (mt->nchars == 0) - { - mtext__free_plist (mt); - mt->plist = plist; - return; - } - if (pos > 0 && pos < mtext_nchars (mt)) - prepare_to_modify (mt, pos, pos, Mnil); - - for (pl_last = NULL, pl = mt->plist; pl; pl_last = pl, pl = pl->next) - { - MInterval *interval, *prev, *next, *head, *tail; - - if (pos == 0) - prev = NULL, next = pl->head; - else if (pos == mtext_nchars (mt)) - prev = pl->tail, next = NULL; - else - { - next = find_interval (pl, pos); - if (next->start < pos) - { - divide_interval (pl, next, pos); - next = next->next; - } - for (i = 0; i < next->nprops; i++) - if (next->stack[i]->start < pos) - split_property (next->stack[i], next); - prev = next->prev; - } - - xassert (check_plist (pl, 0) == 0); - for (p = NULL, pl2 = plist; pl2 && pl->key != pl2->key; - p = pl2, pl2 = p->next); - if (pl2) - { - xassert (check_plist (pl2, pl2->head->start) == 0); - if (p) - p->next = pl2->next; - else - plist = plist->next; - - head = pl2->head; - tail = pl2->tail; - free (pl2); - } - else - { - head = tail = new_interval (pos, pos + nchars); - } - head->prev = prev; - tail->next = next; - if (prev) - prev->next = head; - else - pl->head = head; - if (next) - next->prev = tail; - else - pl->tail = tail; - if (next) - adjust_intervals (next, pl->tail, nchars); - - xassert (check_plist (pl, 0) == 0); - if (prev && prev->nprops > 0) - { - for (interval = prev; - interval->next != next && interval->next->nprops == 0; - interval = interval->next) - for (i = 0; i < interval->nprops; i++) - { - MTextProperty *prop = interval->stack[i]; - - if (prop->control.flag & MTEXTPROP_REAR_STICKY) - PUSH_PROP (interval->next, prop); - } - } - xassert (check_plist (pl, 0) == 0); - if (next && next->nprops > 0) - { - for (interval = next; - interval->prev != prev && interval->prev->nprops == 0; - interval = interval->prev) - for (i = 0; i < interval->nprops; i++) - { - MTextProperty *prop = interval->stack[i]; - - if (prop->control.flag & MTEXTPROP_FRONT_STICKY) - PUSH_PROP (interval->prev, prop); - } - } - - interval = prev ? prev : pl->head; - pl->cache = interval; - while (interval && interval->start <= pos + nchars) - interval = maybe_merge_interval (pl, interval); - xassert (check_plist (pl, 0) == 0); - } - - if (pl_last) - pl_last->next = plist; - else - mt->plist = plist; - - for (; plist; plist = plist->next) - { - plist->cache = plist->head; - if (pos > 0) - { - if (plist->head->nprops) - { - interval = new_interval (0, pos); - interval->next = plist->head; - plist->head->prev = interval; - plist->head = interval; - } - else - plist->head->start = 0; - } - if (pos < mtext_nchars (mt)) - { - if (plist->tail->nprops) - { - interval = new_interval (pos + nchars, - mtext_nchars (mt) + nchars); - interval->prev = plist->tail; - plist->tail->next = interval; - plist->tail = interval; - } - else - plist->tail->end = mtext_nchars (mt) + nchars; - } - xassert (check_plist (plist, 0) == 0); - } -} - -/*** @} */ -#endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */ - - -/** External API */ - -/*** @addtogroup m17nTextProperty */ -/*** @{ */ - -/*=*/ -/***en - @brief Get the value of the topmost text property. - - The mtext_get_prop () function searches the character at $POS in - M-text $MT for the text property whose key is $KEY. - - @return - If a text property is found, mtext_get_prop () returns the value - of the property. If the property has multiple values, it returns - the topmost one. If no such property is found, it returns @c NULL - without changing the external variable #merror_code. - - If an error is detected, mtext_get_prop () returns @c NULL and - assigns an error code to the external variable #merror_code. - - @note If @c NULL is returned without an error, there are two - possibilities: - - @li the character at $POS does not have a property whose key is $KEY, or - - @li the character does have such a property and its value is @c NULL. - - If you need to distinguish these two cases, use the - mtext_get_prop_values () function instead. */ - -/***ja - @brief ¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Î°ìÈÖ¾å¤ÎÃͤòÆÀ¤ë - - ´Ø¿ô mtext_get_prop () ¤Ï¡¢M-text $MT Æâ¤Ç $POS ¤È¤¤¤¦°ÌÃ֤ˤ¢¤ëʸ - »ú¤Î¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥­¡¼¤¬ $KEY ¤Ç¤¢¤ë¤â¤Î¤òõ¤¹¡£ - - @return - ¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Â¸ºß¤¹¤ë¤Ê¤é¡¢mtext_get_prop () ¤Ï¤½¤ÎÃͤòÊÖ - ¤¹¡£Ãͤ¬Ê£¿ô¸ºß¤¹¤ë¤È¤­¤Ï¡¢°ìÈÖ¾å¤ÎÃͤòÊÖ¤¹¡£¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð³°Éô - ÊÑ¿ô #merror_code ¤òÊѹ¹¤¹¤ë¤³¤È¤Ê¤¯ @c NULL ¤òÊÖ¤¹¡£ - - ¥¨¥é¡¼¤¬¸¡½Ð¤µ¤ì¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë - ¥¨¥é¡¼ ¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ - - @note ¥¨¥é¡¼¤Ê¤·¤Ç @c NULL ¤¬ÊÖ¤µ¤ì¤¿¾ì¹ç¤Ë¤ÏÆó¤Ä¤Î²ÄǽÀ­¤¬¤¢¤ë¡£ - - @li $POS ¤Î°ÌÃÖ¤Îʸ»ú¤Ï $KEY ¤ò¥­¡¼¤È¤¹¤ë¥×¥í¥Ñ¥Æ¥£¤ò»ý¤¿¤Ê¤¤¡£ - - @li ¤½¤Îʸ»ú¤Ï $KEY ¤ò¥­¡¼¤È¤¹¤ë¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¤¬¡¢¤½¤ÎÃͤ¬ @c - NULL ¤Ç¤¢¤ë¡£ - - ¤³¤ÎÆó¤Ä¤ò¶èÊ̤¹¤ëɬÍפ¬¤¢¤ë¾ì¹ç¤Ë¤Ï¡¢´Ø¿ô mtext_get_prop_values () - ¤ò»ÈÍѤ¹¤ë¤³¤È¡£ - - @latexonly \IPAlabel{mtext_get_prop} @endlatexonly */ - -/*** - @errors - @c MERROR_RANGE, @c MERROR_SYMBOL - - @seealso - mtext_get_prop_values (), mtext_put_prop (), mtext_put_prop_values (), - mtext_push_prop (), mtext_pop_prop (), mtext_prop_range () */ - -void * -mtext_get_prop (MText *mt, int pos, MSymbol key) -{ - MTextPlist *plist; - MInterval *interval; - void *val; - - M_CHECK_POS (mt, pos, NULL); - - plist = get_plist_create (mt, key, 0); - if (! plist) - return NULL; - - interval = find_interval (plist, pos); - val = (interval->nprops - ? interval->stack[interval->nprops - 1]->val : NULL); - return val; -} - -/*=*/ - -/***en - @brief Get multiple values of a text property - - The mtext_get_prop_values () function searches the character at - $POS in M-text $MT for the property whose key is $KEY. If such - a property is found, its values are stored in the memory area - pointed to by $VALUES. $NUM limits the maximum number of stored - values. - - @return - If the operation was successful, mtext_get_prop_values () returns - the number of actually stored values. If the character at $POS - does not have a property whose key is $KEY, the return value is - 0. If an error is detected, mtext_get_prop_values () returns -1 and - assigns an error code to the external variable #merror_code. */ - -/***ja - @brief ¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÊ£¿ôÆÀ¤ë - - ´Ø¿ô mtext_get_prop_values () ¤Ï¡¢M-text $MT Æâ¤Ç $POS ¤È¤¤¤¦°ÌÃÖ - ¤Ë¤¢¤ëʸ»ú¤Î¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥­¡¼¤¬ $KEY ¤Ç¤¢¤ë¤â¤Î¤òõ¤¹¡£¤â¤·¤½ - ¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬¸«¤Ä¤«¤ì¤Ð¡¢¤½¤ì¤¬»ý¤ÄÃÍ(Ê£¿ô²Ä)¤ò $VALUES ¤Î - »Ø¤¹¥á¥â¥êÎΰè¤Ë³ÊǼ¤¹¤ë¡£$NUM ¤Ï³ÊǼ¤¹¤ëÃͤοô¤Î¾å¸Â¤Ç¤¢¤ë¡£ - - @return - ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¡¢mtext_get_prop_values () ¤Ï¼ÂºÝ¤Ë¥á¥â¥ê¤Ë³ÊǼ¤µ - ¤ì¤¿Ãͤοô¤òÊÖ¤¹¡£$POS ¤Î°ÌÃÖ¤Îʸ»ú¤¬ $KEY ¤ò¥­¡¼¤È¤¹¤ë¥×¥í¥Ñ¥Æ¥£ - ¤ò»ý¤¿¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤¹¡£¥¨¥é¡¼¤¬¸¡½Ð¤µ¤ì¤¿¾ì¹ç¤Ï -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô - #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ - - @latexonly \IPAlabel{mtext_get_prop_values} @endlatexonly */ - -/*** - @errors - @c MERROR_RANGE, @c MERROR_SYMBOL - - @seealso - mtext_get_prop (), mtext_put_prop (), mtext_put_prop_values (), - mtext_push_prop (), mtext_pop_prop (), mtext_prop_range () */ - -int -mtext_get_prop_values (MText *mt, int pos, MSymbol key, - void **values, int num) -{ - MTextPlist *plist; - MInterval *interval; - int nprops; - int i; - int offset; - - M_CHECK_POS (mt, pos, -1); - - plist = get_plist_create (mt, key, 0); - if (! plist) - return 0; - - interval = find_interval (plist, pos); - /* It is assured that INTERVAL is not NULL. */ - nprops = interval->nprops; - if (nprops == 0 || num <= 0) - return 0; - if (nprops == 1 || num == 1) - { - values[0] = interval->stack[nprops - 1]->val; - return 1; - } - - if (nprops <= num) - num = nprops, offset = 0; - else - offset = nprops - num; - for (i = 0; i < num; i++) - values[i] = interval->stack[offset + i]->val; - return num; -} - -/*=*/ - -/***en - @brief Get list of text property keys at a position of an M-text. - - The mtext_get_prop_keys () function creates an array whose - elements are the keys of text properties found at position $POS in - M-text $MT, and sets *$KEYS to the address of the created array. - The user is responsible to free the memory allocated for - the array. - - @returns - - If the operation was successful, mtext_get_prop_keys () returns - the length of the key list. Otherwise it returns -1 and assigns - an error code to the external variable #merror_code. - -*/ - -/***ja - @brief ¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤Î¥ê¥¹¥È¤òÆÀ¤ë - - ´Ø¿ô mtext_get_prop_keys () ¤Ï¡¢M-text $MT Æâ¤Ç $POS ¤Î°ÌÃ֤ˤ¢¤ë - ʸ»ú¤¬»ý¤Ã¤Æ¤¤¤ë¤¹¤Ù¤Æ¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤«¤é¤Ê¤ëÇÛÎó¤òºî¤ê¡¢ - ¤½¤ÎÇÛÎó¤Î¥¢¥É¥ì¥¹¤ò *$KEYS ¤Ë¥»¥Ã¥È¤¹¤ë¡£¤³¤ÎÇÛÎó¤Î¤¿¤á¤Ë³ÎÊݤµ¤ì - ¤¿¥á¥â¥ê¤ò²òÊü¤¹¤ë¤Î¤Ï¥æ¡¼¥¶¤ÎÀÕǤ¤Ç¤¢¤ë¡£ - - @return - ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mtext_get_prop_keys () ¤ÏÆÀ¤é¤ì¤¿¥ê¥¹¥È¤ÎŤµ¤òÊÖ - ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤ò - ÀßÄꤹ¤ë¡£ -*/ - -/*** - @errors - @c MERROR_RANGE - - @seealso - mtext_get_prop (), mtext_put_prop (), mtext_put_prop_values (), - mtext_get_prop_values (), mtext_push_prop (), mtext_pop_prop () */ - -int -mtext_get_prop_keys (MText *mt, int pos, MSymbol **keys) -{ - MTextPlist *plist; - int i; - - M_CHECK_POS (mt, pos, -1); - for (i = 0, plist = mt->plist; plist; i++, plist = plist->next); - if (i == 0) - { - *keys = NULL; - return 0; - } - MTABLE_MALLOC (*keys, i, MERROR_TEXTPROP); - for (i = 0, plist = mt->plist; plist; plist = plist->next) - { - MInterval *interval = find_interval (plist, pos); - - if (interval->nprops) - (*keys)[i++] = plist->key; - } - return i; -} - -/*=*/ - -/***en - @brief Set a text property - - The mtext_put_prop () function sets a text property to the - characters between $FROM (inclusive) and $TO (exclusive) in M-text - $MT. $KEY and $VAL specify the key and the value of the text - property. - -@verbatim - FROM TO -M-text: |<------------|-------- MT ---------|------------>| -PROP : <------------------ OLD_VAL --------------------> -@endverbatim - - becomes - -@verbatim - FROM TO -M-text: |<------------|-------- MT ---------|------------>| -PROP : <-- OLD_VAL-><-------- VAL -------><-- OLD_VAL--> -@endverbatim - - @return - If the operation was successful, mtext_put_prop () returns 0. - Otherwise it returns -1 and assigns an error code to the external - variable #merror_code. */ - -/***ja - @brief ¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤òÀßÄꤹ¤ë - - ´Ø¿ô mtext_put_prop () ¤Ï¡¢M-text $MT ¤Î $FROM ¡Ê´Þ¤Þ¤ì¤ë¡Ë¤«¤é - $TO ¡Ê´Þ¤Þ¤ì¤Ê¤¤¡Ë¤ÎÈϰϤÎʸ»ú¤Ë¡¢¥­¡¼¤¬ $KEY ¤ÇÃͤ¬ $VAL ¤Ç¤¢¤ë¤è - ¤¦¤Ê¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ò¥»¥Ã¥È¤¹¤ë¡£ - - -@verbatim - FROM TO -M-text: |<------------|-------- MT ---------|------------>| -PROP: <------------------ OLD_VAL --------------------> -@endverbatim - -¤Ï¼¡¤Î¤è¤¦¤Ë¤Ê¤ë¡£ - -@verbatim - FROM TO -M-text: |<------------|-------- MT ---------|------------>| -PROP: <-- OLD_VAL-><-------- VAL -------><-- OLD_VAL--> -@endverbatim - - @return - ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mtext_put_prop () ¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 - ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ - - @latexonly \IPAlabel{mtext_put_prop} @endlatexonly */ - -/*** - @errors - @c MERROR_RANGE, @c MERROR_SYMBOL - - @seealso - mtext_put_prop_values (), mtext_get_prop (), - mtext_get_prop_values (), mtext_push_prop (), - mtext_pop_prop (), mtext_prop_range () */ - -int -mtext_put_prop (MText *mt, int from, int to, MSymbol key, void *val) -{ - MTextPlist *plist; - MTextProperty *prop; - MInterval *interval; - - M_CHECK_RANGE (mt, from, to, -1, 0); - - prepare_to_modify (mt, from, to, key); - plist = get_plist_create (mt, key, 1); - interval = pop_all_properties (plist, from, to); - prop = new_text_property (mt, from, to, key, val, 0); - PUSH_PROP (interval, prop); - M17N_OBJECT_UNREF (prop); - if (interval->next) - maybe_merge_interval (plist, interval); - if (interval->prev) - maybe_merge_interval (plist, interval->prev); - xassert (check_plist (plist, 0) == 0); - return 0; -} - -/*=*/ - -/***en - @brief Set multiple text properties with the same key - - The mtext_put_prop_values () function sets a text property to the - characters between $FROM (inclusive) and $TO (exclusive) in M-text - $MT. $KEY and $VALUES specify the key and the values of the text - property. $NUM specifies the number of property values to be set. - - @return - If the operation was successful, mtext_put_prop_values () returns - 0. Otherwise it returns -1 and assigns an error code to the - external variable #merror_code. */ - -/***ja - @brief Ʊ¤¸¥­¡¼¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤òÊ£¿ôÀßÄꤹ¤ë - - ´Ø¿ô mtext_put_prop_values () ¤Ï¡¢M-Text $MT ¤Î$FROM ¡Ê´Þ¤Þ¤ì¤ë¡Ë - ¤«¤é $TO ¡Ê´Þ¤Þ¤ì¤Ê¤¤¡Ë¤ÎÈϰϤÎʸ»ú¤Ë¡¢¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ò¥»¥Ã¥È - ¤¹¤ë¡£¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤Ï$KEY¤Ë¤è¤Ã¤Æ¡¢ÃÍ(Ê£¿ô²Ä)¤Ï$VALUES - ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ë¡£$NUM ¤ÏÀßÄꤵ¤ì¤ëÃͤθĿô¤Ç¤¢¤ë¡£ - - @return - ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¡¢mtext_put_prop_values () ¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤± - ¤ì¤Ð -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ - - @latexonly \IPAlabel{mtext_put_prop_values} @endlatexonly */ - -/*** - @errors - @c MERROR_RANGE, @c MERROR_SYMBOL - - @seealso - mtext_put_prop (), mtext_get_prop (), mtext_get_prop_values (), - mtext_push_prop (), mtext_pop_prop (), mtext_prop_range () */ - -int -mtext_put_prop_values (MText *mt, int from, int to, - MSymbol key, void **values, int num) -{ - MTextPlist *plist; - MInterval *interval; - int i; - - M_CHECK_RANGE (mt, from, to, -1, 0); - - prepare_to_modify (mt, from, to, key); - plist = get_plist_create (mt, key, 1); - interval = pop_all_properties (plist, from, to); - if (num > 0) - { - PREPARE_INTERVAL_STACK (interval, num); - for (i = 0; i < num; i++) - { - MTextProperty *prop - = new_text_property (mt, from, to, key, values[i], 0); - PUSH_PROP (interval, prop); - M17N_OBJECT_UNREF (prop); - } - } - if (interval->next) - maybe_merge_interval (plist, interval); - if (interval->prev) - maybe_merge_interval (plist, interval->prev); - xassert (check_plist (plist, 0) == 0); - return 0; -} - -/*=*/ - -/***en - @brief Push a text property - - The mtext_push_prop () function pushes a text property whose key - is $KEY and value is $VAL to the characters between $FROM - (inclusive) and $TO (exclusive) in $MT. - -@verbatim - FROM TO -M-text: |<------------|-------- MT ---------|------------>| -PROP : <------------------ OLD_VAL --------------------> -@endverbatim - - becomes - -@verbatim - FROM TO -M-text: |<------------|-------- MT ---------|------------>| -PROP : <------------------- OLD_VAL -------------------> -PROP : <-------- VAL -------> -@endverbatim - - @return - If the operation was successful, mtext_push_prop () returns 0. - Otherwise it returns -1 and assigns an error code to the external - variable #merror_code. */ - -/***ja - @brief ¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ò¥×¥Ã¥·¥å¤¹¤ë - - ´Ø¿ô mtext_push_prop () ¤Ï¡¢¥­¡¼¤¬ $KEY ¤ÇÃͤ¬ $VAL ¤Ç¤¢¤ë¥Æ¥­¥¹¥È - ¥×¥í¥Ñ¥Æ¥£¤ò¡¢M-text $MT Ãæ¤Î $FROM ¡Ê´Þ¤Þ¤ì¤ë¡Ë¤«¤é $TO ¡Ê´Þ¤Þ¤ì¤Ê - ¤¤¡Ë¤ÎÈϰϤÎʸ»ú¤Ë¥×¥Ã¥·¥å¤¹¤ë¡£ - -@verbatim - FROM TO -M-text: |<------------|-------- MT ---------|------------>| -PROP : <------------------ OLD_VAL --------------------> -@endverbatim - ¤Ï¼¡¤Î¤è¤¦¤Ë¤Ê¤ë¡£ -@verbatim - FROM TO -M-text: |<------------|-------- MT ---------|------------>| -PROP : <------------------- OLD_VAL -------------------> -PROP : <-------- VAL -------> -@endverbatim - - @return - ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¡¢mtext_push_prop () ¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð - -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ - - @latexonly \IPAlabel{mtext_push_prop} @endlatexonly */ - -/*** - @errors - @c MERROR_RANGE, @c MERROR_SYMBOL - - @seealso - mtext_put_prop (), mtext_put_prop_values (), - mtext_get_prop (), mtext_get_prop_values (), - mtext_pop_prop (), mtext_prop_range () */ - -int -mtext_push_prop (MText *mt, int from, int to, - MSymbol key, void *val) -{ - MTextPlist *plist; - MInterval *head, *tail, *interval; - MTextProperty *prop; - int check_head, check_tail; - - M_CHECK_RANGE (mt, from, to, -1, 0); - - prepare_to_modify (mt, from, to, key); - plist = get_plist_create (mt, key, 1); - - /* Find an interval that covers the position FROM. */ - head = find_interval (plist, from); - - /* If the found interval starts before FROM, divide it at FROM. */ - if (head->start < from) - { - divide_interval (plist, head, from); - head = head->next; - check_head = 0; - } - else - check_head = 1; - - /* Find an interval that ends at TO. If TO is not at the end of an - interval, make one that ends at TO. */ - if (head->end == to) - { - tail = head; - check_tail = 1; - } - else if (head->end > to) - { - divide_interval (plist, head, to); - tail = head; - check_tail = 0; - } - else - { - tail = find_interval (plist, to); - if (! tail) - { - tail = plist->tail; - check_tail = 0; - } - else if (tail->start == to) - { - tail = tail->prev; - check_tail = 1; - } - else - { - divide_interval (plist, tail, to); - check_tail = 0; - } - } - - prop = new_text_property (mt, from, to, key, val, 0); - - /* Push PROP to the current values of intervals between HEAD and TAIL - (both inclusive). */ - for (interval = head; ; interval = interval->next) - { - PUSH_PROP (interval, prop); - if (interval == tail) - break; - } - - M17N_OBJECT_UNREF (prop); - - /* If there is a possibility that TAIL now has the same value as the - next one, check it and concatenate them if necessary. */ - if (tail->next && check_tail) - maybe_merge_interval (plist, tail); - - /* If there is a possibility that HEAD now has the same value as the - previous one, check it and concatenate them if necessary. */ - if (head->prev && check_head) - maybe_merge_interval (plist, head->prev); - - xassert (check_plist (plist, 0) == 0); - return 0; -} - -/*=*/ - -/***en - @brief Pop a text property - - The mtext_pop_prop () function removes the topmost text property - whose key is $KEY from the characters between $FROM (inclusive) - and and $TO (exclusive) in $MT. - - This function does nothing if characters in the region have no - such text property. - -@verbatim - FROM TO -M-text: |<------------|-------- MT ---------|------------>| -PROP : <------------------ OLD_VAL --------------------> -@endverbatim - - becomes - -@verbatim - FROM TO -M-text: |<------------|-------- MT ---------|------------>| -PROP : <--OLD_VAL-->| |<--OLD_VAL-->| -@endverbatim - - @return - If the operation was successful, mtext_pop_prop () return 0. - Otherwise it returns -1 and assigns an error code to the external - variable #merror_code. */ - -/***ja - @brief ¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ò¥Ý¥Ã¥×¤¹¤ë - - ´Ø¿ô mtext_pop_prop () ¤Ï¡¢¥­¡¼¤¬ $KEY ¤Ç¤¢¤ë¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤Î - ¤¦¤Á°ìÈÖ¾å¤Î¤â¤Î¤ò¡¢M-text $MT ¤Î $FROM ¡Ê´Þ¤Þ¤ì¤ë¡Ë¤«¤é $TO¡Ê´Þ¤Þ - ¤ì¤Ê¤¤¡Ë¤ÎÈϰϤÎʸ»ú¤«¤é¼è¤ê½ü¤¯¡£ - - »ØÄêÈϰϤÎʸ»ú¤¬¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤ò»ý¤¿¤Ê¤¤¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï²¿ - ¤â¤·¤Ê¤¤¡£ - -@verbatim - FROM TO -M-text: |<------------|-------- MT ---------|------------>| -PROP : <------------------ OLD_VAL --------------------> -@endverbatim - ¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£ -@verbatim - FROM TO -M-text: |<------------|-------- MT ---------|------------>| -PROP : <--OLD_VAL-->| |<--OLD_VAL-->| -@endverbatim - - @return - ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¡¢mtext_pop_prop () ¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 - ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ - - @latexonly \IPAlabel{mtext_pop_prop} @endlatexonly */ - -/*** - @errors - @c MERROR_RANGE, @c MERROR_SYMBOL - - @seealso - mtext_put_prop (), mtext_put_prop_values (), - mtext_get_prop (), mtext_get_prop_values (), - mtext_push_prop (), mtext_prop_range () */ - -int -mtext_pop_prop (MText *mt, int from, int to, MSymbol key) -{ - MTextPlist *plist; - MInterval *head, *tail; - int check_head = 1; - - if (key == Mnil) - MERROR (MERROR_TEXTPROP, -1); - M_CHECK_RANGE (mt, from, to, -1, 0); - plist = get_plist_create (mt, key, 0); - if (! plist) - return 0; - - /* Find an interval that covers the position FROM. */ - head = find_interval (plist, from); - if (head->end >= to - && head->nprops == 0) - /* No property to pop. */ - return 0; - - prepare_to_modify (mt, from, to, key); - - /* If the found interval starts before FROM and has value(s), divide - it at FROM. */ - if (head->start < from) - { - if (head->nprops > 0) - { - divide_interval (plist, head, from); - check_head = 0; - } - else - from = head->end; - head = head->next; - } - - /* Pop the topmost text property from each interval following HEAD. - Stop at an interval that ends after TO. */ - for (tail = head; tail && tail->end <= to; tail = tail->next) - if (tail->nprops > 0) - POP_PROP (tail); - - if (tail) - { - if (tail->start < to) - { - if (tail->nprops > 0) - { - divide_interval (plist, tail, to); - POP_PROP (tail); - } - to = tail->start; - } - else - to = tail->end; - } - else - to = plist->tail->start; - - /* If there is a possibility that HEAD now has the same text - properties as the previous one, check it and concatenate them if - necessary. */ - if (head->prev && check_head) - head = head->prev; - while (head && head->end <= to) - head = maybe_merge_interval (plist, head); - - xassert (check_plist (plist, 0) == 0); - return 0; -} - -/*=*/ - -/***en - @brief Find the range where the value of a text property is the same. - - The mtext_prop_range () function investigates the extent where all - characters have the same value for a text property. It first - finds the value of the property specified by $KEY of the character - at $POS in M-text $MT. Then it checks if adjacent characters have - the same value for the property $KEY. The beginning and the end - of the found range are stored to the variable pointed to by $FROM - and $TO. The character position stored in $FROM is inclusive but - that in $TO is exclusive; this fashion is compatible with the - range specification in the mtext_put_prop () function, etc. - - If $DEEPER is not 0, not only the topmost but also all the stacked - properties whose key is $KEY are compared. - - If $FROM is @c NULL, the beginning of range is not searched for. If - $TO is @c NULL, the end of range is not searched for. - - @return - - If the operation was successful, mtext_prop_range () returns the - number of values the property $KEY has at pos. Otherwise it - returns -1 and assigns an error code to the external variable @c - merror_code. */ - -/***ja - @brief ¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤¬Æ±¤¸Ãͤò¤È¤ëÈϰϤòÄ´¤Ù¤ë. - - ´Ø¿ô mtext_prop_range () ¤Ï¡¢Ï¢Â³¤·¤¿Ê¸»ú¤¬Æ±¤¸¥×¥í¥Ñ¥Æ¥£¤ÎÃͤò»ý¤Ã - ¤Æ¤¤¤ëÈϰϤòÄ´¤Ù¤ë¡£¤Þ¤º M-text $MT ¤Î $POS ¤Î°ÌÃ֤ˤ¢¤ëʸ»ú¤Î¥×¥í - ¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥­¡¼ $KEY ¤Ç»ØÄꤵ¤ì¤¿¤â¤Î¤ÎÃͤò¸«¤Ä¤±¤ë¡£¤½¤·¤ÆÁ°¸å - ¤Îʸ»ú¤â$KEY ¤Î¥×¥í¥Ñ¥Æ¥£¤ËƱ¤¸Ãͤò¤â¤Ã¤Æ¤¤¤ë¤«¤É¤¦¤«¤òÄ´¤Ù¤ë¡£¸« - ¤Ä¤±¤¿ÈϰϤκǽé¤ÈºÇ¸å¤ò¡¢¤½¤ì¤¾¤ì $FROM ¤È $TO ¤ò¥Ý¥¤¥ó¥¿¤È¤¹¤ëÊÑ - ¿ô¤ËÊݸ¤¹¤ë¡£$FROM ¤ËÊݸ¤µ¤ì¤ëʸ»ú¤Î°ÌÃ֤ϸ«¤Ä¤±¤¿ÈϰϤ˴ޤޤì¤ë - ¤¬¡¢$TO ¤Ï´Þ¤Þ¤ì¤Ê¤¤¡£¡Ê$TO ¤ÎÁ°¤ÇƱ¤¸Ãͤò¤È¤ëÈϰϤϽª¤ï¤ë¡£¡Ë¤³¤Î - ÈÏ°Ï»ØÄê¤ÎÊýË¡¤Ï¡¢´Ø¿ô mtext_put_prop () ¤Ê¤É¤È¶¦Ä̤Τâ¤Î¤Ç¤¢¤ë¡£ - - $DEEPER ¤¬ 0 ¤Ç¤Ê¤±¤ì¤Ð¡¢$KEY ¤È¤¤¤¦¥­¡¼¤ò»ý¤Ä¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á°ìÈÖ - ¾å¤Î¤â¤Î¤À¤±¤Ç¤Ê¤¯¡¢¥¹¥¿¥Ã¥¯Ãæ¤Î¤¹¤Ù¤Æ¤Î¤â¤Î¤¬Èæ³Ó¤µ¤ì¤ë¡£ - - $FROM ¤¬ @c NULL ¤Ê¤é¤Ð¡¢ÈϰϤλϤޤê¤Ïõº÷¤·¤Ê¤¤¡£$TO ¤¬ @c NULL - ¤Ê¤é¤Ð¡¢ÈϰϤνª¤ê¤Ïõº÷¤·¤Ê¤¤¡£ - - @return - ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¡¢mtext_prop_range () ¤Ï $KEY ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤοô¤ò - ÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð-1 ¤òÊÖ¤·¡¢ ³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼ - ¥É¤òÀßÄꤹ¤ë¡£ - - @latexonly \IPAlabel{mtext_prop_range} @endlatexonly */ - -/*** - @errors - @c MERROR_RANGE, @c MERROR_SYMBOL - - @seealso - mtext_put_prop (), mtext_put_prop_values (), - mtext_get_prop (), mtext_get_prop_values (), - mtext_pop_prop (), mtext_push_prop () */ - -int -mtext_prop_range (MText *mt, MSymbol key, int pos, - int *from, int *to, int deeper) -{ - MTextPlist *plist; - MInterval *interval, *temp; - void *val; - int nprops; - - M_CHECK_POS (mt, pos, -1); - - plist = get_plist_create (mt, key, 0); - if (! plist) - { - if (from) *from = 0; - if (to) *to = mtext_nchars (mt); - return 0; - } - - interval = find_interval (plist, pos); - nprops = interval->nprops; - if (deeper || ! nprops) - { - if (from) *from = interval->start; - if (to) *to = interval->end; - return interval->nprops; - } - - val = nprops ? interval->stack[nprops - 1] : NULL; - - if (from) - { - for (temp = interval; - temp->prev - && (temp->prev->nprops - ? (nprops - && (val == temp->prev->stack[temp->prev->nprops - 1])) - : ! nprops); - temp = temp->prev); - *from = temp->start; - } - - if (to) - { - for (temp = interval; - temp->next - && (temp->next->nprops - ? (nprops - && val == temp->next->stack[temp->next->nprops - 1]) - : ! nprops); - temp = temp->next); - *to = temp->end; - } - - return nprops; -} - -/***en - @brief Create a text property. - - The mtext_property () function returns a newly allocated text - property whose key is $KEY and value is $VAL. The text created - property is not attached to any M-text, i.e. it is detached. - - $CONTROL_BITS must be 0 or logical OR of @c enum @c - MTextPropertyControl. */ - -MTextProperty * -mtext_property (MSymbol key, void *val, int control_bits) -{ - return new_text_property (NULL, 0, 0, key, val, control_bits); -} - -/***en - @brief Return the M-text of a text property. - - The mtext_property_mtext () function returns the M-text to which - text property $PROP is attached. If $PROP is currently detached, - NULL is returned. */ - -MText * -mtext_property_mtext (MTextProperty *prop) -{ - return prop->mt; -} - -/***en - @brief Return the key of a text property. - - The mtext_property_key () function returns the key (symbol) of - text property $PROP. */ - -MSymbol -mtext_property_key (MTextProperty *prop) -{ - return prop->key; -} - -/***en - @brief Return the value of a text property. - - The mtext_property_value () function returns the value of text - property $PROP. */ - -void * -mtext_property_value (MTextProperty *prop) -{ - return prop->val; -} - -/***en - @brief Return the start position of a text property. - - The mtext_property_start () function returns the start position of - text property $PROP. The start position is a character position - of an M-text where $PROP begins. If $PROP is detached, it returns - -1. */ - -int -mtext_property_start (MTextProperty *prop) -{ - return (prop->mt ? prop->start : -1); -} - -/***en - @brief Return the end position of a text property. - - The mtext_property_end () function returns the end position of - text property $PROP. The end position is a character position of - an M-text where $PROP ends. If $PROP is detached, it returns - -1. */ - -int -mtext_property_end (MTextProperty *prop) -{ - return (prop->mt ? prop->end : -1); -} - -/***en - @brief Get the topmost text property. - - The mtext_get_property () function searches the character at $POS - in M-text $MT for a text property whose key is $KEY. - - @return - If a text property is found, mtext_get_property () returns it. If - there are multiple text properties, it returns the topmost one. - If no such property is found, it returns @c NULL without changing - the external variable #merror_code. - - If an error is detected, mtext_get_property () returns @c NULL and - assigns an error code to the external variable #merror_code. */ - -MTextProperty * -mtext_get_property (MText *mt, int pos, MSymbol key) -{ - MTextPlist *plist; - MInterval *interval; - - M_CHECK_POS (mt, pos, NULL); - - plist = get_plist_create (mt, key, 0); - if (! plist) - return NULL; - - interval = find_interval (plist, pos); - if (! interval->nprops) - return NULL; - return interval->stack[interval->nprops - 1]; -} - -/***en - @brief Get multiple text properties. - - The mtext_get_properties () function searches the character at - $POS in M-text $MT for properties whose key is $KEY. If such - properties are found, they are stored in the memory area pointed - to by $PROPS. $NUM limits the maximum number of stored - properties. - - @return - If the operation was successful, mtext_get_properties () returns - the number of actually stored properties. If the character at - $POS does not have a property whose key is $KEY, the return value - is 0. If an error is detected, mtext_get_properties () returns -1 - and assigns an error code to the external variable #merror_code. */ - -int -mtext_get_properties (MText *mt, int pos, MSymbol key, - MTextProperty **props, int num) -{ - MTextPlist *plist; - MInterval *interval; - int nprops; - int i; - int offset; - - M_CHECK_POS (mt, pos, -1); - - plist = get_plist_create (mt, key, 0); - if (! plist) - return 0; - - interval = find_interval (plist, pos); - /* It is assured that INTERVAL is not NULL. */ - nprops = interval->nprops; - if (nprops == 0 || num <= 0) - return 0; - if (nprops == 1 || num == 1) - { - props[0] = interval->stack[nprops - 1]; - return 1; - } - - if (nprops <= num) - num = nprops, offset = 0; - else - offset = nprops - num; - for (i = 0; i < num; i++) - props[i] = interval->stack[offset + i]; - return num; -} - -/***en - @brief Attach a text property to an M-text. - - The mtext_attach_property () function attaches text property $PROP - to the range between $FROM and $TO in M-text $MT. If $PROP is - already attached to an M-text, it is detached before attached to - $MT. - - @return - If the operation was successful, mtext_attach_property () returns - 0. Otherwise it returns -1 and assigns an error code to the - external variable #merror_code. */ - -int -mtext_attach_property (MText *mt, int from, int to, MTextProperty *prop) -{ - MTextPlist *plist; - MInterval *interval; - - M_CHECK_RANGE (mt, from, to, -1, 0); - - M17N_OBJECT_REF (prop); - if (prop->mt) - mtext_detach_property (prop); - prepare_to_modify (mt, from, to, prop->key); - plist = get_plist_create (mt, prop->key, 1); - xassert (check_plist (plist, 0) == 0); - interval = pop_all_properties (plist, from, to); - xassert (check_plist (plist, 0) == 0); - prop->mt = mt; - prop->start = from; - prop->end = to; - PUSH_PROP (interval, prop); - M17N_OBJECT_UNREF (prop); - xassert (check_plist (plist, 0) == 0); - if (interval->next) - maybe_merge_interval (plist, interval); - if (interval->prev) - maybe_merge_interval (plist, interval->prev); - xassert (check_plist (plist, 0) == 0); - return 0; -} - -/***en - @brief Detach a text property from an M-text. - - The mtext_detach_property () function makes text property $PROP - detached. - - @return - This function always returns 0. */ - -int -mtext_detach_property (MTextProperty *prop) -{ - MTextPlist *plist; - int start = prop->start, end = prop->end; - - if (! prop->mt) - return 0; - prepare_to_modify (prop->mt, start, end, prop->key); - plist = get_plist_create (prop->mt, prop->key, 0); - xassert (plist); - detach_property (plist, prop, NULL); - return 0; -} - -/***en - @brief Push a text property onto an M-text. - - The mtext_push_property () function attaches text property $PROP on - M-text MT by the "push" manner. - - @return - If the operation was successful, mtext_push_property () returns - 0. Otherwise it returns -1 and assigns an error code to the - external variable #merror_code. */ - -int -mtext_push_property (MText *mt, int from, int to, MTextProperty *prop) -{ - MTextPlist *plist; - MInterval *head, *tail, *interval; - int check_head, check_tail; - - M_CHECK_RANGE (mt, from, to, -1, 0); - - M17N_OBJECT_REF (prop); - if (prop->mt) - mtext_detach_property (prop); - prepare_to_modify (mt, from, to, prop->key); - plist = get_plist_create (mt, prop->key, 1); - prop->mt = mt; - prop->start = from; - prop->end = to; - - /* Find an interval that covers the position FROM. */ - head = find_interval (plist, from); - - /* If the found interval starts before FROM, divide it at FROM. */ - if (head->start < from) - { - divide_interval (plist, head, from); - head = head->next; - check_head = 0; - } - else - check_head = 1; - - /* Find an interval that ends at TO. If TO is not at the end of an - interval, make one that ends at TO. */ - if (head->end == to) - { - tail = head; - check_tail = 1; - } - else if (head->end > to) - { - divide_interval (plist, head, to); - tail = head; - check_tail = 0; - } - else - { - tail = find_interval (plist, to); - if (! tail) - { - tail = plist->tail; - check_tail = 0; - } - else if (tail->start == to) - { - tail = tail->prev; - check_tail = 1; - } - else - { - divide_interval (plist, tail, to); - check_tail = 0; - } - } - - /* Push PROP to the current values of intervals between HEAD and TAIL - (both inclusive). */ - for (interval = head; ; interval = interval->next) - { - PUSH_PROP (interval, prop); - if (interval == tail) - break; - } - - /* If there is a possibility that TAIL now has the same value as the - next one, check it and concatenate them if necessary. */ - if (tail->next && check_tail) - maybe_merge_interval (plist, tail); - - /* If there is a possibility that HEAD now has the same value as the - previous one, check it and concatenate them if necessary. */ - if (head->prev && check_head) - maybe_merge_interval (plist, head->prev); - - M17N_OBJECT_UNREF (prop); - xassert (check_plist (plist, 0) == 0); - return 0; -} - -/***en - @brief Symbol for specifying serializer functions. - - To serialize a text property, the user must supply a serializer - function for that text property. This is done by giving a symbol - property whose key is #Mtext_prop_serializer and value is a - pointer to an appropriate serializer function. - - @seealso Mtext_prop_serializer (), MTextPropSerializeFunc - */ -MSymbol Mtext_prop_serializer; - -/***en - @brief Symbol for specifying deserializer functions. - - To deserialize a text property, the user must supply a deserializer - function for that text property. This is done by giving a symbol - property whose key is #Mtext_prop_deserializer and value is a - pointer to an appropriate deserializer function. - - @seealso Mtext_prop_serializer (), MTextPropSerializeFunc - */ -MSymbol Mtext_prop_deserializer; - -/***en - @brief Serialize text properties in an M-text. - - The mtext_serialize () function serializes the text between $FROM - and $TO in M-text $MT. The serialized result is an M-text in the - form of XML. $PROPERTY_LIST limits the text properties to be - serialized. If a symbol 1) appears as the value of an element in - $PROPERTY_LIST (the key must be @c Mt ) and 2) has the symbol - property #Mtext_prop_serializer, a text property having that - symbol as its key is turned into the "property" element in the - resulting XML representation. - - The DTD of the generated XML is as follows: - -@verbatim - - - - - - - - - ]> -@endverbatim - - This function depends on the libxml2 library. If the m17n library - is configured without libxml2, this function always fails. - - @return - If the operation was successful, mtext_serialize () returns an - M-text in the form of XML. Otherwise it returns @c NULL and assigns an - error code to the external variable #merror_code. - - @seealso - mtext_deserialize (), Mtext_prop_serializer */ - -MText * -mtext_serialize (MText *mt, int from, int to, MPlist *property_list) -{ -#ifdef HAVE_XML2 - MPlist *plist, *pl; - MTextPropSerializeFunc func; - MText *work; - xmlDocPtr doc; - xmlNodePtr node; - unsigned char *ptr; - int n; - - M_CHECK_RANGE (mt, from, to, NULL, NULL); - doc = xmlParseMemory (XML_TEMPLATE, strlen (XML_TEMPLATE) + 1); - node = xmlDocGetRootElement (doc); - - plist = mplist (); - MPLIST_DO (pl, property_list) - { - MSymbol key = MPLIST_VAL (pl); - - func = (MTextPropSerializeFunc) msymbol_get (key, Mtext_prop_serializer); - if (func) - extract_text_properties (mt, from, to, key, plist); - } - - work = mtext (); - MPLIST_DO (pl, plist) - { - MTextProperty *prop = MPLIST_VAL (pl); - char buf[256]; - MPlist *serialized_plist; - xmlNodePtr child; - - func = (MTextPropSerializeFunc) msymbol_get (prop->key, - Mtext_prop_serializer); - serialized_plist = (func) (prop->val); - if (! serialized_plist) - continue; - mtext_reset (work); - mplist__serialize (work, serialized_plist); - child = xmlNewChild (node, NULL, (xmlChar *) "property", NULL); - xmlSetProp (child, (xmlChar *) "key", - (xmlChar *) MSYMBOL_NAME (prop->key)); - xmlSetProp (child, (xmlChar *) "value", (xmlChar *) MTEXT_DATA (work)); - sprintf (buf, "%d", prop->start - from); - xmlSetProp (child, (xmlChar *) "from", (xmlChar *) buf); - sprintf (buf, "%d", prop->end - from); - xmlSetProp (child, (xmlChar *) "to", (xmlChar *) buf); - sprintf (buf, "%d", prop->control.flag); - xmlSetProp (child, (xmlChar *) "control", (xmlChar *) buf); - xmlAddChild (node, xmlNewText ((xmlChar *) "\n")); - - M17N_OBJECT_UNREF (serialized_plist); - } - M17N_OBJECT_UNREF (plist); - - if (from > 0 || to < mtext_nchars (mt)) - mtext_copy (work, 0, mt, from, to); - else - { - M17N_OBJECT_UNREF (work); - work = mt; - } - for (from = 0, to = mtext_nchars (mt); from <= to; from++) - { - ptr = MTEXT_DATA (mt) + POS_CHAR_TO_BYTE (mt, from); - xmlNewTextChild (node, NULL, (xmlChar *) "body", (xmlChar *) ptr); - from = mtext_character (mt, from, to, 0); - if (from < 0) - from = to; - } - - xmlDocDumpMemoryEnc (doc, (xmlChar **) &ptr, &n, "UTF-8"); - if (work == mt) - work = mtext (); - mtext__cat_data (work, ptr, n, MTEXT_FORMAT_UTF_8); - return work; -#else /* not HAVE_XML2 */ - MERROR (MERROR_TEXTPROP, NULL); -#endif /* not HAVE_XML2 */ -} - -/***en - @brief Deserialize text properties in an M-text. - - The mtext_deserialize () function deserializes M-text $MT. $MT - must be an XML having the followng DTD. - -@verbatim - - - - - - - - - ]> -@endverbatim - - This function depends on the libxml2 library. If the m17n library - is configured without libxml2, this function always fail. - - @return - If the operation was successful, mtext_deserialize () returns the - resulting M-text. Otherwise it returns @c NULL and assigns an error - code to the external variable #merror_code. - - @seealso - mtext_serialize (), Mtext_prop_deserializer */ - -MText * -mtext_deserialize (MText *mt) -{ -#ifdef HAVE_XML2 - xmlDocPtr doc; - xmlNodePtr node; - xmlXPathContextPtr context; - xmlXPathObjectPtr result; - xmlChar *body_str, *key_str, *val_str, *from_str, *to_str, *ctl_str; - int i; - - if (mt->format > MTEXT_FORMAT_UTF_8) - MERROR (MERROR_TEXTPROP, NULL); - doc = xmlParseMemory ((char *) MTEXT_DATA (mt), mtext_nbytes (mt)); - if (! doc) - MERROR (MERROR_TEXTPROP, NULL); - node = xmlDocGetRootElement (doc); - if (! node) - { - xmlFreeDoc (doc); - MERROR (MERROR_TEXTPROP, NULL); - } - if (xmlStrcmp (node->name, (xmlChar *) "mtext")) - { - xmlFreeDoc (doc); - MERROR (MERROR_TEXTPROP, NULL); - } - - context = xmlXPathNewContext (doc); - result = xmlXPathEvalExpression ((xmlChar *) "//body", context); - if (xmlXPathNodeSetIsEmpty (result->nodesetval)) - { - xmlFreeDoc (doc); - MERROR (MERROR_TEXTPROP, NULL); - } - for (i = 0, mt = mtext (); i < result->nodesetval->nodeNr; i++) - { - if (i > 0) - mtext_cat_char (mt, 0); - node = (xmlNodePtr) result->nodesetval->nodeTab[i]; - body_str = xmlNodeListGetString (doc, node->xmlChildrenNode, 1); - if (body_str) - { - mtext__cat_data (mt, body_str, strlen ((char *) body_str), - MTEXT_FORMAT_UTF_8); - xmlFree (body_str); - } - } - - result = xmlXPathEvalExpression ((xmlChar *) "//property", context); - if (! xmlXPathNodeSetIsEmpty (result->nodesetval)) - for (i = 0; i < result->nodesetval->nodeNr; i++) - { - MSymbol key; - MTextPropDeserializeFunc func; - MTextProperty *prop; - MPlist *plist; - int from, to, control; - void *val; - - key_str = xmlGetProp (result->nodesetval->nodeTab[i], - (xmlChar *) "key"); - val_str = xmlGetProp (result->nodesetval->nodeTab[i], - (xmlChar *) "value"); - from_str = xmlGetProp (result->nodesetval->nodeTab[i], - (xmlChar *) "from"); - to_str = xmlGetProp (result->nodesetval->nodeTab[i], - (xmlChar *) "to"); - ctl_str = xmlGetProp (result->nodesetval->nodeTab[i], - (xmlChar *) "control"); - - key = msymbol ((char *) key_str); - func = ((MTextPropDeserializeFunc) - msymbol_get (key, Mtext_prop_deserializer)); - if (! func) - continue; - plist = mplist__from_string (val_str, strlen ((char *) val_str)); - if (! plist) - continue; - if (sscanf ((char *) from_str, "%d", &from) != 1 - || from < 0 || from >= mtext_nchars (mt)) - continue; - if (sscanf ((char *) to_str, "%d", &to) != 1 - || to <= from || to > mtext_nchars (mt)) - continue; - if (sscanf ((char *) ctl_str, "%d", &control) != 1 - || control < 0 || control > MTEXTPROP_CONTROL_MAX) - continue; - val = (func) (plist); - M17N_OBJECT_UNREF (plist); - prop = mtext_property (key, val, control); - if (key->managing_key) - M17N_OBJECT_UNREF (val); - mtext_push_property (mt, from, to, prop); - M17N_OBJECT_UNREF (prop); - - xmlFree (key_str); - xmlFree (val_str); - xmlFree (from_str); - xmlFree (to_str); - xmlFree (ctl_str); - } - xmlXPathFreeContext (context); - xmlFreeDoc (doc); - return mt; -#else /* not HAVE_XML2 */ - MERROR (MERROR_TEXTPROP, NULL); -#endif /* not HAVE_XML2 */ -} - -/*** @} */ - -/* - Local Variables: - coding: euc-japan - End: -*/ diff --git a/src/textprop.h b/src/textprop.h deleted file mode 100644 index 30e75b6..0000000 --- a/src/textprop.h +++ /dev/null @@ -1,69 +0,0 @@ -/* textproc.h -- header file for the text property module. - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H15PRO112 - - This file is part of the m17n library. - - The m17n library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - The m17n library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. */ - -#ifndef _M17N_TEXTPROP_H_ -#define _M17N_TEXTPROP_H_ - -/** MTextProperty is the structure for a text property object. While - attached, it is stored in the stacks of intervals covering the - range from MTextProperty->start to MTextProperty->end. */ - -struct MTextProperty -{ - /** Common header for a managed object. */ - M17NObject control; - - /** Number of intervals the property is attached. When it becomes - zero, the property is detached. */ - unsigned attach_count; - - /** M-text to which the property is attaced. The value NULL means - that the property is detached. */ - MText *mt; - - /** Region of if the property is attached to it. */ - int start, end; - - /** Key of the property. */ - MSymbol key; - - /** Value of the property. */ - void *val; -}; - - -extern struct MTextPlist *mtext__copy_plist (struct MTextPlist *, - int from, int to, - MText *mt, int pos); - -extern void mtext__free_plist (MText *mt); - -extern void mtext__adjust_plist_for_delete (MText *, int, int); - -extern void mtext__adjust_plist_for_insert (MText *, int, int, - struct MTextPlist *); - -extern void mtext__adjust_plist_for_change (MText *mt, int from, int to); - -extern void dump_textplist (struct MTextPlist *plist, int indent); - -#endif /* _M17N_TEXTPROP_H_ */ -- 1.7.10.4