From: tomo Date: Tue, 9 Mar 2004 05:26:37 +0000 (+0000) Subject: This commit was manufactured by cvs2svn to create branch 'unlabeled-1.1.2'. X-Git-Url: http://git.chise.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5dfd0e4dd1801093af80e4d10cb812221be5975e;p=m17n%2Fm17n-lib.git This commit was manufactured by cvs2svn to create branch 'unlabeled-1.1.2'. --- 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_ */