From: Koichi KAMICHI Date: Tue, 3 Feb 2004 16:11:30 +0000 (+0000) Subject: Initial revision X-Git-Url: http://git.chise.org/gitweb/?a=commitdiff_plain;h=b755cadf536858496296e43b30baec2cd9ec8c13;p=chise%2Fkage.git Initial revision --- b755cadf536858496296e43b30baec2cd9ec8c13 diff --git a/kagecgi/.DS_Store b/kagecgi/.DS_Store new file mode 100644 index 0000000..1a57a1e Binary files /dev/null and b/kagecgi/.DS_Store differ diff --git a/kagecgi/COPYING b/kagecgi/COPYING new file mode 100644 index 0000000..a52b16e --- /dev/null +++ b/kagecgi/COPYING @@ -0,0 +1,341 @@ + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +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 give any other recipients of the Program a copy of this License +along with the Program. + +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 Program or any portion +of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +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 Program, 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 Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) 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; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, 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 executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or 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 counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program 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. + + 5. 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 Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. 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 Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program 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 Program. + +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. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program 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. + + 9. The Free Software Foundation may publish revised and/or new versions +of the 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 Program +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 Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, 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 + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), 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 Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. 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) 19yy + + This program 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 of the License, or + (at your option) any later version. + + This program is distributed in the hope that 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 this program; 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. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/kagecgi/Makefile b/kagecgi/Makefile new file mode 100755 index 0000000..1e88ed3 --- /dev/null +++ b/kagecgi/Makefile @@ -0,0 +1,37 @@ +# +# +# CC=gcc -g +CC= gcc -Wall + +VERSION=0.0.1 + +#for cygwin with glib gdk gtk +#CFLAGS= -I/usr/local/include -I/usr/local/include/glib-2.0 -I/usr/local/include/glib-2.0/glib -I/usr/local/include/glib-2.0/gobject -I/usr/local/include/gtk-2.0 -I/usr/local/include/gtk-2.0/gtk -I/usr/local/include/gtk-2.0/gdk -I/usr/local/include/gtk-2.0/gdk-pixbuf -I/usr/local/lib/glib-2.0/include -I/usr/local/lib/gtk-2.0/include -I/usr/local/include/pango-1.0 -I/usr/local/include/atk-1.0 +#LIBS= -lpng -ldb -L/usr/local/lib -lglib-2.0 -lgtk-win32-2.0 -lgdk-win32-2.0 -lgthread-2.0 -lpangowin32-1.0 -lgobject-2.0 -lgmodule-2.0 -lpangoft2-1.0 -lpango-1.0 -latk-1.0 -lgdk_pixbuf-2.0 + +#for cygwin with glib +#CFLAGS= -I/usr/local/include -I/usr/local/include/glib-2.0 -I/usr/local/include/glib-2.0/glib -I/usr/local/lib/glib-2.0/include +#LIBS= -L/usr/local/lib -lpng -ldb -lglib-2.0 + +#for linux +CFLAGS= -I/usr/local/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/X11R6/include +LIBS= -L/usr/local/lib -lpng -ldb -lglib-2.0 -L/usr/X11R6/lib -lX11 + +kage.cgi: kagecgi.o kagepng.o kagedf.o kagecd.o kageic.o kagepoly.o kagedb.o kageeg.o kagecomb.o kagechar.o kagetool.o + $(CC) $(CFLAGS) -o kage.cgi kagecgi.o kagepng.o kagedf.o kagecd.o kageic.o kagepoly.o kagedb.o kageeg.o kagecomb.o kagechar.o kagetool.o $(LIBS) + +kagecgi.o: kagecgi.c +kagedf.o: kagedf.c +kagecd.o: kagecd.c +kageic.o: kageic.c +kagepoly.o: kagepoly.c +kagedb.o: kagedb.c +kageeg.o: kageeg.c +kagechar.o: kagechar.c +kagecomb.o: kagecomb.c +kagetool.o: kagetool.c +kagepng.o: kagepng.c + +clean: + \rm -r -f *.o *~ *.exe *.cgi *.stackdump + diff --git a/kagecgi/error.png b/kagecgi/error.png new file mode 100755 index 0000000..4c3a4d2 Binary files /dev/null and b/kagecgi/error.png differ diff --git a/kagecgi/kage.h b/kagecgi/kage.h new file mode 100755 index 0000000..b11c5c6 --- /dev/null +++ b/kagecgi/kage.h @@ -0,0 +1,57 @@ +//kage.h +// +#include +#include +#include + +#ifndef _KAGE_H_ +#define _KAGE_H_ + +int kShotai; +#define kMincho 0 +#define kGothic 1 + +#define kMage 10 +#define kRate 20 +#define kResolution (1000 / kRate + 1) * 2 +#define kMinWidthY 2 +#define kMinWidthT 6 +#define kWidth 5 +#define kKakato 3 //has KAKATO = 2, no KAKATO = 1 +#define kKasane 3 +#define kMixdot (kWidth * 2) * (kWidth * 2 - 1) + +#define kMaxIDSSequenceLength 16 +#define kMaxIDCLength 16 +#define kMaxStrokeDataLength 256 // over 12(digits per integer with +/- flag) * 11(columns) + 1(line end) + +struct kPoint{ + int X; + int Y; +}; + +XPoint xpoly[kResolution]; + +struct kPoint poly[kResolution]; +struct kPoint poly2[3]; +struct kPoint poly3[5]; +struct kPoint poly4[4]; + +struct EDGE { + struct EDGE *next; + long yTop, yBot; + long xNowWhole, xNowNum, xNowDen, xNowDir; + long xNowNumStep; +}; + +#define SGN(a) ( (a) > 0 ? 1 : ( (a) < 0 ? -1 : 0 ) ) + +//kagedf.c +void dfDrawFont(int, int, int, int, int, int, int, int, int, int, int); +//kagecd.c +void cdDrawCurve(int, int, int, int, int, int, int, int); +void cdDrawLine(int, int, int, int, int, int); +//kageic.c +void icPolygon(struct kPoint *, int); + +#endif diff --git a/kagecgi/kagecd.c b/kagecgi/kagecd.c new file mode 100755 index 0000000..93fc8e2 --- /dev/null +++ b/kagecgi/kagecd.c @@ -0,0 +1,1087 @@ +//kagecd.c +// +#include "kage.h" + +void cdDrawCurve(int x1, int y1, + int x2, int y2, + int x3, int y3, + int a1, int a2){ + + double rad, t; + double x, y, v; + double ix, iy, ia, ib, ir; + int ox1, oy1, ox2, oy2; + int count, tt; + int delta; + double deltad; + double XX, XY, YX, YY; + + if(kShotai == kMincho){ // mincho + switch(a1){ + case 0: + case 7: + delta = -1 * kMinWidthY * 0.5; + break; + case 1: + case 2: + case 6: + case 22: + delta = 0; + break; + case 12: + case 32: + delta = kMinWidthY; + break; + default: + break; + } + + if(x1 == x2){ + if(y1 < y2){ y1 = y1 - delta; } + else{ y1 = y1 + delta; } + } + else if(y1 == y2){ + if(x1 < x2){ x1 = x1 - delta; } + else{ x1 = x1 + delta; } + } + else{ + rad = atan((double)(y2 - y1) / (double)(x2 - x1)); + if(x1 < x2){ v = 1; } else{ v = -1; } + x1 = x1 - delta * cos(rad) * v; + y1 = y1 - delta * sin(rad) * v; + } + + switch(a2){ + case 0: + case 1: + case 8: + case 7: + case 9: + case 15: + case 14: + case 17: + case 5: + delta = 0; + break; + default: + break; + } + + if(x2 == x3){ + if(y2 < y3){ y3 = y3 + delta; } + else{ y3 = y3 - delta; } + } + else if(y2 == y3){ + if(x2 < x3){ x3 = x3 + delta; } + else{ x3 = x3 - delta; } + } + else{ + rad = atan((double)(y3 - y2) / (double)(x3 - x2)); + if(x2 < x3){ v = 1; } else{ v = -1; } + x3 = x3 + delta * cos(rad) * v; + y3 = y3 + delta * sin(rad) * v; + } + + count = 0; + + for(tt = 0; tt <= 1000; tt = tt + kRate){ + t = (double)(tt) / 1000; + + //calculate a dot + x = ((1.0 - t) * (1.0 - t) * x1 + 2.0 * t * (1.0 - t) * x2 + t * t * x3); + y = ((1.0 - t) * (1.0 - t) * y1 + 2.0 * t * (1.0 - t) * y2 + t * t * y3); + + //KATAMUKI of vector by BIBUN + ix = (x1 - 2.0 * x2 + x3) * 2.0 * t + (-2.0 * x1 + 2.0 * x2); + iy = (y1 - 2.0 * y2 + y3) * 2.0 * t + (-2.0 * y1 + 2.0 * y2); + + //line SUICHOKU by vector + if(ix != 0 && iy != 0){ + ir = atan(iy / ix * -1.0); + ia = sin(ir) * (double)(kMinWidthT); + ib = cos(ir) * (double)(kMinWidthT); + } + else if(ix == 0){ + ia = kMinWidthT; + ib = 0; + } + else{ + ia = 0; + ib = kMinWidthT; + } + + if(a1 == 7 && a2 != 17){ deltad = sqrt(t); } + else if(a2 == 7 && a1 != 17){ deltad = sqrt(1.0 - t); } + else if(a1 == 7 && a2 == 17){ deltad = sqrt(t / 2); } + else if(a1 == 17 && a2 != 7){ deltad = sqrt(t / 2 + 0.5); } + else if(a1 != 7 && a2 == 17){ deltad = sqrt(1.0 - t / 2); } + else if(a1 == 17 && a2 == 7){ deltad = sqrt(0.5 - t / 2); } + else{ deltad = 1; } + ia = ia * deltad; + ib = ib * deltad; + + //swap if two lines are crossing + if(((x + ia) - ox1) * ((x + ia) - ox1) + + ((y + ib) - oy1) * ((y + ib) - oy1) > + ((x - ia) - ox1) * ((x - ia) - ox1) + + ((y - ib) - oy1) * ((y - ib) - oy1) && count != 0){ + ia = ia * -1; + ib = ib * -1; + } + + //copy as an old point + ox1 = x + ia; + oy1 = y + ib; + ox2 = x - ia; + oy2 = y - ib; + + //copy to polygon structuer + poly[count].X = x + ia; + poly[count].Y = y + ib; + poly[(1000 / kRate + 1) * 2 - 1 - count].X = x - ia; + poly[(1000 / kRate + 1) * 2 - 1 - count].Y = y - ib; + count += 1; + } + + icPolygon(poly, (1000 / kRate + 1) * 2); + + //process for head of stroke + rad = atan((double)(y2 - y1) / (double)(x2 - x1)); + if(x1 < x2){ v = 1; } else{ v = -1; } + XX = sin(rad) * v; + XY = cos(rad) * v * -1; + YX = cos(rad) * v; + YY = sin(rad) * v; + + if(a1 == 12){ + if(x1 == x2){ + poly2[0].X = x1 - kMinWidthT; + poly2[0].Y = y1; + poly2[1].X = x1 + kMinWidthT; + poly2[1].Y = y1; + poly2[2].X = x1 - kMinWidthT; + poly2[2].Y = y1 - kMinWidthT; + icPolygon(poly2, 3); + } + else{ + poly2[0].X = x1 - kMinWidthT * XX; + poly2[0].Y = y1 - kMinWidthT * XY; + poly2[1].X = x1 + kMinWidthT * XX; + poly2[1].Y = y1 + kMinWidthT * XY; + poly2[2].X = x1 - kMinWidthT * XX - kMinWidthT * YX; + poly2[2].Y = y1 - kMinWidthT * XY - kMinWidthT * YY; + icPolygon(poly2, 3); + } + } + + if(a1 == 0){ + if(y1 <= y3){ //from up to bottom + if(x1 == x2){ + poly2[0].X = x1 - kMinWidthT; + poly2[0].Y = y1; + poly2[1].X = x1 + kMinWidthT; + poly2[1].Y = y1; + poly2[2].X = x1 - kMinWidthT; + poly2[2].Y = y1 - kMinWidthY; + icPolygon(poly2, 3); + } + else{ + poly2[0].X = x1 - kMinWidthT * XX; + poly2[0].Y = y1 - kMinWidthT * XY; + poly2[1].X = x1 + kMinWidthT * XX; + poly2[1].Y = y1 + kMinWidthT * XY; + poly2[2].X = x1 - kMinWidthT * XX - kMinWidthY * YX; + poly2[2].Y = y1 - kMinWidthT * XY - kMinWidthY * YY; + icPolygon(poly2, 3); + } + } + else{ //bottom to up + if(x1 == x2){ //is it right? + poly2[0].X = x1 - kMinWidthT; + poly2[0].Y = y1; + poly2[1].X = x1 + kMinWidthT; + poly2[1].Y = y1; + poly2[2].X = x1 - kMinWidthT; + poly2[2].Y = y1 + kMinWidthY; + icPolygon(poly2, 3); + } + else{ + poly2[0].X = x1 - kMinWidthT * XX; + poly2[0].Y = y1 - kMinWidthT * XY; + poly2[1].X = x1 + kMinWidthT * XX; + poly2[1].Y = y1 + kMinWidthT * XY; + poly2[2].X = x1 + kMinWidthT * XX - kMinWidthY * YX; + poly2[2].Y = y1 + kMinWidthT * XY - kMinWidthY * YY; + icPolygon(poly2, 3); + } + } + } + + if(a1 == 22){ //box's up-right corner, any time same degree + poly3[0].X = x1 - kMinWidthT; + poly3[0].Y = y1 - kMinWidthY; + poly3[1].X = x1; + poly3[1].Y = y1 - kMinWidthY - kWidth; + poly3[2].X = x1 + kMinWidthT + kWidth; + poly3[2].Y = y1 + kMinWidthY; + poly3[3].X = x1 + kMinWidthT; + poly3[3].Y = y1 + kMinWidthT; + poly3[4].X = x1 - kMinWidthT; + poly3[4].Y = y1; + icPolygon(poly3, 5); + } + + if(a1 == 0){ //beginning of the stroke + if(y1 <= y3){ //from up to bottom + if(x1 == x2){ + poly2[0].X = x1 + kMinWidthT; + poly2[0].Y = y1 + kMinWidthY * 0.5; + poly2[1].X = x1 + kMinWidthT + kMinWidthT * 0.5; + poly2[1].Y = y1 + kMinWidthY * 0.5 + kMinWidthY; + poly2[2].X = x1 + kMinWidthT; + poly2[2].Y = y1 + kMinWidthY * 0.5 + kMinWidthY * 2; + icPolygon(poly2, 3); + } + else{ + poly2[0].X = x1 + kMinWidthT * XX + (kMinWidthY * 0.5) * YX; + poly2[0].Y = y1 + kMinWidthT * XY + (kMinWidthY * 0.5) * YY; + poly2[1].X = x1 + (kMinWidthT + kMinWidthT * 0.5) * XX + (kMinWidthY * 0.5 + kMinWidthY) * YX; + poly2[1].Y = y1 + (kMinWidthT + kMinWidthT * 0.5) * XY + (kMinWidthY * 0.5 + kMinWidthY) * YY; + poly2[2].X = x1 + kMinWidthT * XX + (kMinWidthY * 0.5 + kMinWidthY * 2) * YX; + poly2[2].Y = y1 + kMinWidthT * XY + (kMinWidthY * 0.5 + kMinWidthY * 2) * YY; + icPolygon(poly2, 3); + } + } + else{ //from bottom to up + if(x1 == x2){ //is it right? + poly2[0].X = x1 + kMinWidthT; + poly2[0].Y = y1 - kMinWidthY * 0.5; + poly2[1].X = x1 + kMinWidthT + kMinWidthT * 0.5; + poly2[1].Y = y1 - kMinWidthY * 0.5 - kMinWidthY; + poly2[2].X = x1 + kMinWidthT; + poly2[2].Y = y1 - kMinWidthY * 0.5 - kMinWidthY * 2; + icPolygon(poly2, 3); + } + else //SETSUGOUMEN GA KAKERUNODE HOKYOU + poly3[0].X = x1 - (kMinWidthT - 1) * XX + (kMinWidthY * 0.5) * YX; + poly3[0].Y = y1 - (kMinWidthT - 1) * XY + (kMinWidthY * 0.5) * YY; + poly3[1].X = x1 - (kMinWidthT - 0) * XX + (kMinWidthY * 0.5) * YX; + poly3[1].Y = y1 - (kMinWidthT - 0) * XY + (kMinWidthY * 0.5) * YY; + poly3[2].X = x1 - (kMinWidthT + kMinWidthT * 0.5) * XX + (kMinWidthY * 0.5 + kMinWidthY) * YX; + poly3[2].Y = y1 - (kMinWidthT + kMinWidthT * 0.5) * XY + (kMinWidthY * 0.5 + kMinWidthY) * YY; + poly3[3].X = x1 - (kMinWidthT - 0) * XX + (kMinWidthY * 0.5 + kMinWidthY * 2) * YX; + poly3[3].Y = y1 - (kMinWidthT - 0) * XY + (kMinWidthY * 0.5 + kMinWidthY * 2) * YY; + poly3[4].X = x1 - (kMinWidthT - 1) * XX + (kMinWidthY * 0.5 + kMinWidthY * 2) * YX; + poly3[4].Y = y1 - (kMinWidthT - 1) * XY + (kMinWidthY * 0.5 + kMinWidthY * 2) * YY; + icPolygon(poly3, 5); + } + } + + //process for tail + rad = atan((double)(y3 - y2) / (double)(x3 - x2)); + if(x2 < x3){ v = 1; } else{ v = -1; } + YX = sin(rad) * v * -1; + YY = cos(rad) * v; + XX = cos(rad) * v; + XY = sin(rad) * v; + + if(a2 == 1 || a2 == 8 || a2 == 15){ //the last filled circle + if(x2 == x3){ + poly3[0].X = x3 - kMinWidthT; + poly3[0].Y = y3; + poly3[1].X = x3 - kMinWidthT * 0.6; + poly3[1].Y = y3 + kMinWidthT * 0.6; + poly3[2].X = x3; + poly3[2].Y = y3 + kMinWidthT; + poly3[3].X = x3 + kMinWidthT * 0.6; + poly3[3].Y = y3 + kMinWidthT * 0.6; + poly3[4].X = x3 + kMinWidthT; + poly3[4].Y = y3; + icPolygon(poly3, 5); + } + else if(y2 == y3){ + poly3[0].X = x3; + poly3[0].Y = y3 - kMinWidthT; + poly3[1].X = x3 + kMinWidthT * 0.6; + poly3[1].Y = y3 - kMinWidthT * 0.6; + poly3[2].X = x3 + kMinWidthT; + poly3[2].Y = y3; + poly3[3].X = x3 + kMinWidthT * 0.6; + poly3[3].Y = y3 + kMinWidthT * 0.6; + poly3[4].X = x3; + poly3[4].Y = y3 + kMinWidthT; + icPolygon(poly3, 5); + } + else{ + poly3[0].X = x3 + sin(rad) * kMinWidthT * v; + poly3[0].Y = y3 - cos(rad) * kMinWidthT * v; + poly3[1].X = x3 + cos(rad) * kMinWidthT * 0.8 * v + sin(rad) * kMinWidthT * 0.6 * v; + poly3[1].Y = y3 + sin(rad) * kMinWidthT * 0.8 * v - cos(rad) * kMinWidthT * 0.6 * v; + poly3[2].X = x3 + cos(rad) * kMinWidthT * v; + poly3[2].Y = y3 + sin(rad) * kMinWidthT * v; + poly3[3].X = x3 + cos(rad) * kMinWidthT * 0.8 * v - sin(rad) * kMinWidthT * 0.6 * v; + poly3[3].Y = y3 + sin(rad) * kMinWidthT * 0.8 * v + cos(rad) * kMinWidthT * 0.6 * v; + poly3[4].X = x3 - sin(rad) * kMinWidthT * v; + poly3[4].Y = y3 + cos(rad) * kMinWidthT * v; + icPolygon(poly3, 5); + } + } + + if(a2 == 17){ //the last filled half circle + if(x2 == x3){ + poly3[0].X = x3 - kMinWidthT * 0.5; + poly3[0].Y = y3; + poly3[1].X = x3 - kMinWidthT * 0.6 * 0.5; + poly3[1].Y = y3 + kMinWidthT * 0.6 * 0.5; + poly3[2].X = x3; + poly3[2].Y = y3 + kMinWidthT * 0.5; + poly3[3].X = x3 + kMinWidthT * 0.6 * 0.5; + poly3[3].Y = y3 + kMinWidthT * 0.6 * 0.5; + poly3[4].X = x3 + kMinWidthT * 0.5; + poly3[4].Y = y3; + icPolygon(poly3, 5); + } + else if(y2 == y3){ + poly3[0].X = x3; + poly3[0].Y = y3 - kMinWidthT * 0.5; + poly3[1].X = x3 + kMinWidthT * 0.6 * 0.5; + poly3[1].Y = y3 - kMinWidthT * 0.6 * 0.5; + poly3[2].X = x3 + kMinWidthT * 0.5; + poly3[2].Y = y3; + poly3[3].X = x3 + kMinWidthT * 0.6 * 0.5; + poly3[3].Y = y3 + kMinWidthT * 0.6 * 0.5; + poly3[4].X = x3; + poly3[4].Y = y3 + kMinWidthT * 0.5; + icPolygon(poly3, 5); + } + else{ + poly3[0].X = x3 + sin(rad) * kMinWidthT * 0.5 * v; + poly3[0].Y = y3 - cos(rad) * kMinWidthT * 0.5 * v; + poly3[1].X = x3 + cos(rad) * kMinWidthT * 0.8 * 0.5 * v + sin(rad) * kMinWidthT * 0.6 * 0.5 * v; + poly3[1].Y = y3 + sin(rad) * kMinWidthT * 0.8 * 0.5 * v - cos(rad) * kMinWidthT * 0.6 * 0.5 * v; + poly3[2].X = x3 + cos(rad) * kMinWidthT * 0.5 * v; + poly3[2].Y = y3 + sin(rad) * kMinWidthT * 0.5 * v; + poly3[3].X = x3 + cos(rad) * kMinWidthT * 0.5 * 0.8 * v - sin(rad) * kMinWidthT * 0.6 * 0.5 * v; + poly3[3].Y = y3 + sin(rad) * kMinWidthT * 0.5 * 0.8 * v + cos(rad) * kMinWidthT * 0.6 * 0.5 * v; + poly3[4].X = x3 - sin(rad) * kMinWidthT * 0.5 * v; + poly3[4].Y = y3 + cos(rad) * kMinWidthT * 0.5 * v; + icPolygon(poly3, 5); + } + } + + if(a2 == 9){ + if(y2 == y3){ + poly2[0].X = x3; + poly2[0].Y = y3 + kMinWidthT; + poly2[1].X = x3; + poly2[1].Y = y3 - kMinWidthT; + poly2[2].X = x3 + kMinWidthT; + poly2[2].Y = y3 - kMinWidthT; + icPolygon(poly2, 3); + } + else{ + poly2[0].X = x3 + kMinWidthT * YX; + poly2[0].Y = y3 + kMinWidthT * YY; + poly2[1].X = x3 - kMinWidthT * YX; + poly2[1].Y = y3 - kMinWidthT * YY; + poly2[2].X = x3 + kMinWidthT * XX - kMinWidthT * YX; + poly2[2].Y = y3 + kMinWidthT * XY - kMinWidthT * YY; + icPolygon(poly2, 3); + } + } + + if(a2 == 15){ //jump up + if(y2 == y3){ + poly4[0].X = x3; + poly4[0].Y = y3 - kMinWidthT + 1; + poly4[1].X = x3 + 2; + poly4[1].Y = y3 - kMinWidthT - kWidth * 5; + poly4[2].X = x3; + poly4[2].Y = y3 - kMinWidthT - kWidth * 5; + poly4[3].X = x3 - kMinWidthT; + poly4[3].Y = y3 - kMinWidthT + 1; + icPolygon(poly4, 4); + } + else{ + poly4[0].X = x3 + (kMinWidthT - 1) * sin(rad) * v; + poly4[0].Y = y3 - (kMinWidthT - 1) * cos(rad) * v; + poly4[1].X = x3 + 2 * cos(rad) * v + (kMinWidthT + kWidth * 5) * sin(rad) * v; + poly4[1].Y = y3 + 2 * sin(rad) * v - (kMinWidthT + kWidth * 5) * cos(rad) * v; + poly4[2].X = x3 + (kMinWidthT + kWidth * 5) * sin(rad) * v; + poly4[2].Y = y3 - (kMinWidthT + kWidth * 5) * cos(rad) * v; + poly4[3].X = x3 + (kMinWidthT - 1) * sin(rad) * v - kMinWidthT * cos(rad) * v; + poly4[3].Y = y3 - (kMinWidthT - 1) * cos(rad) * v - kMinWidthT * sin(rad) * v; + icPolygon(poly4, 4); + } + } + + if(a2 == 14){ //jump to left, allways go left + poly4[0].X = x3; + poly4[0].Y = y3; + poly4[1].X = x3; + poly4[1].Y = y3 - kMinWidthT; + poly4[2].X = x3 - kWidth * 4; + poly4[2].Y = y3 - kMinWidthT; + poly4[3].X = x3 - kWidth * 4; + poly4[3].Y = y3 - kMinWidthT * 0.5; + icPolygon(poly4, 4); + } + } + else{ //gothic + if(a1 % 10 == 2){ + if(x1 == x2){ + if(y1 < y2){ y1 = y1 - kWidth; } else{ y1 = y1 + kWidth; } + } + else if(y1 == y2){ + if(x1 < x2){ x1 = x1 - kWidth; } else{ x1 = x1 + kWidth; } + } + else{ + rad = atan((double)(y2 - y1) / (double)(x2 - x1)); + if(x1 < x2){ v = 1; } else{ v = -1; } + x1 = x1 - kWidth * cos(rad) * v; + y1 = y1 - kWidth * sin(rad) * v; + } + } + + if(a1 % 10 == 3){ + if(x1 == x2){ + if(y1 < y2){ + y1 = y1 - kWidth * kKakato; + } + else{ + y1 = y1 + kWidth * kKakato; + } + } + else if(y1 == y2){ + if(x1 < x2){ + x1 = x1 - kWidth * kKakato; + } + else{ + x1 = x1 + kWidth * kKakato; + } + } + else{ + rad = atan((double)(y2 - y1) / (double)(x2 - x1)); + if(x1 < x2){ v = 1; } else{ v = -1; } + x1 = x1 - kWidth * cos(rad) * v * kKakato; + y1 = y1 - kWidth * sin(rad) * v * kKakato; + } + } + if(a2 % 10 == 2){ + if(x2 == x3){ + if(y2 < y3){ y3 = y3 + kWidth; } else{ y3 = y3 - kWidth; } + } + else if(y2 == y3){ + if(x2 < x3){ x3 = x3 + kWidth; } else{ x3 = x3 - kWidth; } + } + else{ + rad = atan((double)(y3 - y2) / (double)(x3 - x2)); + if(x2 < x3){ v = 1; } else{ v = -1; } + x3 = x3 + kWidth * cos(rad) * v; + y3 = y3 + kWidth * sin(rad) * v; + } + } + + if(a2 % 10 == 3){ + if(x2 == x3){ + if(y2 < y3){ + y3 = y3 + kWidth * kKakato; + } + else{ + y3 = y3 - kWidth * kKakato; + } + } + else if(y2 == y3){ + if(x2 < x3){ + x3 = x3 + kWidth * kKakato; + } + else{ + x3 = x3 - kWidth * kKakato; + } + } + else{ + rad = atan((double)(y3 - y2) / (double)(x3 - x2)); + if(x2 < x3){ v = 1; } else{ v = -1; } + x3 = x3 + kWidth * cos(rad) * v * kKakato; + y3 = y3 + kWidth * sin(rad) * v * kKakato; + } + } + + count = 0; + + for(tt = 0; tt <= 1000; tt = tt + kRate){ + t = (double)tt / 1000; + + //calculating each point + x = ((1.0 - t) * (1.0 - t) * x1 + 2.0 * t * (1.0 - t) * x2 + t * t * x3); + y = ((1.0 - t) * (1.0 - t) * y1 + 2.0 * t * (1.0 - t) * y2 + t * t * y3); + + //SESSEN NO KATAMUKI NO KEISAN(BIBUN) + ix = (x1 - 2.0 * x2 + x3) * 2.0 * t + (-2.0 * x1 + 2.0 * x2); + iy = (y1 - 2.0 * y2 + y3) * 2.0 * t + (-2.0 * y1 + 2.0 * y2); + + //SESSEN NI SUICHOKU NA CHOKUSEN NO KEISAN + if(kShotai == kMincho){ //always false ? + if(ix != 0 && iy != 0){ + ir = atan(iy / ix * -1.0); + ia = sin(ir) * (double)kMinWidthT; + ib = cos(ir) * (double)kMinWidthT; + } + else if(ix == 0){ + ia = kMinWidthT; + ib = 0; + } + else{ + ia = 0; + ib = kMinWidthT; + } + ia = ia * sqrt(1.0 - t); + ib = ib * sqrt(1.0 - t); + } + else{ + if(ix != 0 && iy != 0){ + ir = atan(iy / ix * -1.0); + ia = sin(ir) * (double)kWidth; + ib = cos(ir) * (double)kWidth; + } + else if(ix == 0){ + ia = kWidth; + ib = 0; + } + else{ + ia = 0; + ib = kWidth; + } + } + + //if it is crossing, swap each other + if(((x + ia) - ox1) * ((x + ia) - ox1) + + ((y + ib) - oy1) * ((y + ib) - oy1) > + ((x - ia) - ox1) * ((x - ia) - ox1) + + ((y - ib) - oy1) * ((y - ib) - oy1) && count != 0){ + ia = ia * -1; + ib = ib * -1; + } + + //save old points for calculate crossing + ox1 = x + ia; + oy1 = y + ib; + ox2 = x - ia; + oy2 = y - ib; + + //save to polygon + poly[count].X = x + ia; + poly[count].Y = y + ib; + poly[(1000 / kRate + 1) * 2 - 1 - count].X = x - ia; + poly[(1000 / kRate + 1) * 2 - 1 - count].Y = y - ib; + count += 1; + } + + icPolygon(poly, (1000 / kRate + 1) * 2); + } +} + +void cdDrawLine(int tx1, int ty1, int tx2, int ty2, int ta1, int ta2){ + double rad; + int v, x1, y1, x2, y2, a1, a2; + double XX, XY, YX, YY; + + if(kShotai == kMincho){ //mincho + x1 = tx1; + y1 = ty1; + x2 = tx2; + y2 = ty2; + a1 = ta1; + a2 = ta2; + + if(x1 == x2){ //if TATE stroke, use y-axis + switch(a1){ + case 0: + poly[0].X = x1 - kMinWidthT; + poly[0].Y = y1 - kMinWidthY / 2; + poly[3].X = x1 + kMinWidthT; + poly[3].Y = y1 + kMinWidthY / 2; + break; + case 1: + case 6: + case 22: + poly[0].X = x1 - kMinWidthT; + poly[0].Y = y1; + poly[3].X = x1 + kMinWidthT; + poly[3].Y = y1; + break; + case 12: + poly[0].X = x1 - kMinWidthT; + poly[0].Y = y1 - kMinWidthY - kMinWidthT; + poly[3].X = x1 + kMinWidthT; + poly[3].Y = y1 - kMinWidthY; + break; + case 32: + poly[0].X = x1 - kMinWidthT; + poly[0].Y = y1 - kMinWidthY; + poly[3].X = x1 + kMinWidthT; + poly[3].Y = y1 - kMinWidthY; + break; + } + + switch(a2){ + case 0: + if(a1 == 6){ //KAGI's tail + poly[1].X = x2 - kMinWidthT; + poly[1].Y = y2; + poly[2].X = x2 + kMinWidthT; + poly[2].Y = y2; + } + else{ + poly[1].X = x2 - kMinWidthT; + poly[1].Y = y2 + kMinWidthT / 2; + poly[2].X = x2 + kMinWidthT; + poly[2].Y = y2 - kMinWidthT / 2; + } + break; + case 1: + poly[1].X = x2 - kMinWidthT; + poly[1].Y = y2; + poly[2].X = x2 + kMinWidthT; + poly[2].Y = y2; + break; + case 13: + poly[1].X = x2 - kMinWidthT; + poly[1].Y = y2 + kWidth * kKakato + kMinWidthT; + poly[2].X = x2 + kMinWidthT; + poly[2].Y = y2 + kWidth * kKakato; + break; + case 23: + poly[1].X = x2 - kMinWidthT; + poly[1].Y = y2 + kWidth * kKakato * 0.5 + kMinWidthT; + poly[2].X = x2 + kMinWidthT; + poly[2].Y = y2 + kWidth * kKakato * 0.5; + break; + case 32: + poly[1].X = x2 - kMinWidthT; + poly[1].Y = y2 + kMinWidthY; + poly[2].X = x2 + kMinWidthT; + poly[2].Y = y2 + kMinWidthY; + break; + } + + icPolygon(poly, 4); + + if(a1 == 22){ //box's right top corner + poly3[0].X = x1 - kMinWidthT; + poly3[0].Y = y1 - kMinWidthY; + poly3[1].X = x1; + poly3[1].Y = y1 - kMinWidthY - kWidth; + poly3[2].X = x1 + kMinWidthT + kWidth; + poly3[2].Y = y1 + kMinWidthY; + poly3[3].X = x1 + kMinWidthT; + poly3[3].Y = y1 + kMinWidthT; + poly3[4].X = x1 - kMinWidthT; + poly3[4].Y = y1; + icPolygon(poly3, 5); + } + + if(a1 == 0){ //beginning of the stroke + poly2[0].X = x1 + kMinWidthT; + poly2[0].Y = y1 + kMinWidthY * 0.5; + poly2[1].X = x1 + kMinWidthT + kMinWidthT * 0.5; + poly2[1].Y = y1 + kMinWidthY * 0.5 + kMinWidthY; + poly2[2].X = x1 + kMinWidthT; + poly2[2].Y = y1 + kMinWidthY * 0.5 + kMinWidthY * 2; + icPolygon(poly2, 3); + } + + if((a1 == 6 && a2 == 0) || a2 == 1){ //KAGI NO YOKO BOU NO SAIGO NO MARU + poly3[0].X = x2 - kMinWidthT; + poly3[0].Y = y2; + poly3[1].X = x2 - kMinWidthT * 0.6; + poly3[1].Y = y2 + kMinWidthT * 0.6; + poly3[2].X = x2; + poly3[2].Y = y2 + kMinWidthT; + poly3[3].X = x2 + kMinWidthT * 0.6; + poly3[3].Y = y2 + kMinWidthT * 0.6; + poly3[4].X = x2 + kMinWidthT; + poly3[4].Y = y2; + icPolygon(poly3, 5); + } + } + else if(y1 == y2){ //if it is YOKO stroke, use x-axis + if(a1 == 6){ //if it is KAGI's YOKO stroke, get bold + poly[0].X = x1; + poly[0].Y = y1 - kMinWidthT; + poly[1].X = x2; + poly[1].Y = y2 - kMinWidthT; + poly[2].X = x2; + poly[2].Y = y2 + kMinWidthT; + poly[3].X = x1; + poly[3].Y = y1 + kMinWidthT; + icPolygon(poly, 4); + + if(a2 == 1 || a2 == 0 || a2 == 5){ + //KAGI NO YOKO BOU NO SAIGO NO MARU + poly3[0].X = x2; + poly3[0].Y = y2 - kMinWidthT; + poly3[1].X = x2 + kMinWidthT * 0.6; + poly3[1].Y = y2 - kMinWidthT * 0.6; + poly3[2].X = x2 + kMinWidthT; + poly3[2].Y = y2; + poly3[3].X = x2 + kMinWidthT * 0.6; + poly3[3].Y = y2 + kMinWidthT * 0.6; + poly3[4].X = x2; + poly3[4].Y = y2 + kMinWidthT; + icPolygon(poly3, 5); + } + + if(a2 == 5){ + //KAGI NO YOKO BOU NO HANE + poly[0].X = x2; + poly[0].Y = y2 - kMinWidthT + 1; + poly[1].X = x2 + 2; + poly[1].Y = y2 - kMinWidthT - kWidth * 5; + poly[2].X = x2; + poly[2].Y = y2 - kMinWidthT - kWidth * 5; + poly[3].X = x2 - kMinWidthT; + poly[3].Y = y2 - kMinWidthT + 1; + icPolygon(poly, 4); + } + } + else{ + switch(a1){ + case 0: + poly[0].X = x1; + poly[0].Y = y1 - kMinWidthY; + poly[3].X = x1; + poly[3].Y = y1 + kMinWidthY; + break; + case 2: + poly[0].X = x1 - kMinWidthT; + poly[0].Y = y1 - kMinWidthY; + poly[3].X = x1 - kMinWidthT; + poly[3].Y = y1 + kMinWidthY; + break; + } + + switch(a2){ + case 0: + poly[1].X = x2; + poly[1].Y = y2 - kMinWidthY; + poly[2].X = x2; + poly[2].Y = y2 + kMinWidthY; + break; + case 2: + poly[1].X = x2 + kMinWidthT; + poly[1].Y = y2 - kMinWidthY; + poly[2].X = x2 + kMinWidthT; + poly[2].Y = y2 + kMinWidthY; + } + + icPolygon(poly, 4); + + //UROKO + if(a2 == 0){ + poly2[0].X = x2; + poly2[0].Y = y2 - kMinWidthY; + poly2[1].X = x2 - 24; + poly2[1].Y = y2; + poly2[2].X = x2 - 12; + poly2[2].Y = y2 - 12; + icPolygon(poly2, 3); + } + } + } + else{ //for others, use x-axis + rad = atan((double)(y2 - y1) / (double)(x2 - x1)); + if((abs(y2 - y1) < abs(x2 - x1)) && (a1 != 6) && (a2 != 6)){ //ASAI KAUDO + switch(a1){ //must be 0 or 2 + case 0: + poly[0].X = x1 + sin(rad) * kMinWidthY; + poly[0].Y = y1 - cos(rad) * kMinWidthY; + poly[3].X = x1 - sin(rad) * kMinWidthY; + poly[3].Y = y1 + cos(rad) * kMinWidthY; + break; + case 2: + poly[0].X = x1 + sin(rad) * kMinWidthY - kMinWidthT * cos(rad); + poly[0].Y = y1 - cos(rad) * kMinWidthY - kMinWidthT * sin(rad); + poly[3].X = x1 - sin(rad) * kMinWidthY - kMinWidthT * cos(rad); + poly[3].Y = y1 + cos(rad) * kMinWidthY - kMinWidthT * sin(rad); + break; + } + + switch(a2){ //must be 0 or 2 + case 0: + poly[1].X = x2 + sin(rad) * kMinWidthY; + poly[1].Y = y2 - cos(rad) * kMinWidthY; + poly[2].X = x2 - sin(rad) * kMinWidthY; + poly[2].Y = y2 + cos(rad) * kMinWidthY; + break; + case 2: + poly[1].X = x2 + sin(rad) * kMinWidthY + kMinWidthT * cos(rad); + poly[1].Y = y2 - cos(rad) * kMinWidthY + kMinWidthT * sin(rad); + poly[2].X = x2 - sin(rad) * kMinWidthY + kMinWidthT * cos(rad); + poly[2].Y = y2 + cos(rad) * kMinWidthY + kMinWidthT * sin(rad); + } + + icPolygon(poly, 4); + + //UROKO + if(a2 == 0){ + poly2[0].X = x2 + sin(rad) * kMinWidthY; + poly2[0].Y = y2 - cos(rad) * kMinWidthY; + poly2[1].X = x2 - cos(rad) * 24; + poly2[1].Y = y2 - sin(rad) * 24; + poly2[2].X = x2 - cos(rad) * 12 + sin(rad) * 12; + poly2[2].Y = y2 - sin(rad) * 12 - cos(rad) * 12; + icPolygon(poly2, 3); + } + } + + else{ //KAKUDO GA FUKAI or KAGI NO YOKO BOU + if(x1 > x2){ v = -1; } else{ v = 1; } + switch(a1){ + case 0: + poly[0].X = x1 + sin(rad) * kMinWidthT * v + kMinWidthY * cos(rad) * 0.5 * v; + poly[0].Y = y1 - cos(rad) * kMinWidthT * v + kMinWidthY * sin(rad) * 0.5 * v; + poly[3].X = x1 - sin(rad) * kMinWidthT * v - kMinWidthY * cos(rad) * 0.5 * v; + poly[3].Y = y1 + cos(rad) * kMinWidthT * v - kMinWidthY * sin(rad) * 0.5 * v; + break; + case 1: + case 6: + case 22: + poly[0].X = x1 + sin(rad) * kMinWidthT * v; + poly[0].Y = y1 - cos(rad) * kMinWidthT * v; + poly[3].X = x1 - sin(rad) * kMinWidthT * v; + poly[3].Y = y1 + cos(rad) * kMinWidthT * v; + break; + case 12: + poly[0].X = x1 + sin(rad) * kMinWidthT * v - kMinWidthY * cos(rad) * v; + poly[0].Y = y1 - cos(rad) * kMinWidthT * v - kMinWidthY * sin(rad) * v; + poly[3].X = x1 - sin(rad) * kMinWidthT * v - (kMinWidthT + kMinWidthY) * cos(rad) * v; + poly[3].Y = y1 + cos(rad) * kMinWidthT * v - (kMinWidthT + kMinWidthY) * sin(rad) * v; + break; + case 32: + poly[0].X = x1 + sin(rad) * kMinWidthT * v - kMinWidthY * cos(rad) * v; + poly[0].Y = y1 - cos(rad) * kMinWidthT * v - kMinWidthY * sin(rad) * v; + poly[3].X = x1 - sin(rad) * kMinWidthT * v - kMinWidthY * cos(rad) * v; + poly[3].Y = y1 + cos(rad) * kMinWidthT * v - kMinWidthY * sin(rad) * v; + break; + } + + switch(a2){ + case 0: + if(a1 == 6){ + poly[1].X = x2 + sin(rad) * kMinWidthT * v; + poly[1].Y = y2 - cos(rad) * kMinWidthT * v; + poly[2].X = x2 - sin(rad) * kMinWidthT * v; + poly[2].Y = y2 + cos(rad) * kMinWidthT * v; + } + else{ + poly[1].X = x2 + sin(rad) * kMinWidthT * v - kMinWidthT * 0.5 * cos(rad) * v; + poly[1].Y = y2 - cos(rad) * kMinWidthT * v - kMinWidthT * 0.5 * sin(rad) * v; + poly[2].X = x2 - sin(rad) * kMinWidthT * v + kMinWidthT * 0.5 * cos(rad) * v; + poly[2].Y = y2 + cos(rad) * kMinWidthT * v + kMinWidthT * 0.5 * sin(rad) * v; + } + break; + case 1: + case 5: + poly[1].X = x2 + sin(rad) * kMinWidthT * v; + poly[1].Y = y2 - cos(rad) * kMinWidthT * v; + poly[2].X = x2 - sin(rad) * kMinWidthT * v; + poly[2].Y = y2 + cos(rad) * kMinWidthT * v; + break; + case 13: + poly[1].X = x2 + sin(rad) * kMinWidthT * v + kWidth * kKakato * cos(rad) * v; + poly[1].Y = y2 - cos(rad) * kMinWidthT * v + kWidth * kKakato * sin(rad) * v; + poly[2].X = x2 - sin(rad) * kMinWidthT * v + (kWidth * kKakato + kMinWidthT) * cos(rad) * v; + poly[2].Y = y2 + cos(rad) * kMinWidthT * v + (kWidth * kKakato + kMinWidthT) * sin(rad) * v; + break; + case 23: + poly[1].X = x2 + sin(rad) * kMinWidthT * v + kWidth * kKakato * 0.5 * cos(rad) * v; + poly[1].Y = y2 - cos(rad) * kMinWidthT * v + kWidth * kKakato * 0.5 * sin(rad) * v; + poly[2].X = x2 - sin(rad) * kMinWidthT * v + (kWidth * kKakato * 0.5 + kMinWidthT) * cos(rad) * v; + poly[2].Y = y2 + cos(rad) * kMinWidthT * v + (kWidth * kKakato * 0.5 + kMinWidthT) * sin(rad) * v; + break; + case 32: + poly[1].X = x2 + sin(rad) * kMinWidthT * v + kMinWidthY * cos(rad) * v; + poly[1].Y = y2 - cos(rad) * kMinWidthT * v + kMinWidthY * sin(rad) * v; + poly[2].X = x2 - sin(rad) * kMinWidthT * v + kMinWidthY * cos(rad) * v; + poly[2].Y = y2 + cos(rad) * kMinWidthT * v + kMinWidthY * sin(rad) * v; + break; + } + + icPolygon(poly, 4); + + if((a1 == 6) && (a2 == 0 || a2 == 5)){ //KAGI NO YOKO BOU NO SAIGO NO MARU + poly3[0].X = x2 + sin(rad) * kMinWidthT * v; + poly3[0].Y = y2 - cos(rad) * kMinWidthT * v; + poly3[1].X = x2 + cos(rad) * kMinWidthT * 0.8 * v + sin(rad) * kMinWidthT * 0.6 * v; + poly3[1].Y = y2 + sin(rad) * kMinWidthT * 0.8 * v - cos(rad) * kMinWidthT * 0.6 * v; + poly3[2].X = x2 + cos(rad) * kMinWidthT * v; + poly3[2].Y = y2 + sin(rad) * kMinWidthT * v; + poly3[3].X = x2 + cos(rad) * kMinWidthT * 0.8 * v - sin(rad) * kMinWidthT * 0.6 * v; + poly3[3].Y = y2 + sin(rad) * kMinWidthT * 0.8 * v + cos(rad) * kMinWidthT * 0.6 * v; + poly3[4].X = x2 - sin(rad) * kMinWidthT * v; + poly3[4].Y = y2 + cos(rad) * kMinWidthT * v; + icPolygon(poly3, 5); + } + + if(a1 == 6 && a2 == 5){ + //KAGI NO YOKO BOU NO HANE + poly[0].X = x2 + (kMinWidthT - 1) * sin(rad) * v; + poly[0].Y = y2 - (kMinWidthT - 1) * cos(rad) * v; + poly[1].X = x2 + 2 * cos(rad) * v + (kMinWidthT + kWidth * 5) * sin(rad) * v; + poly[1].Y = y2 + 2 * sin(rad) * v - (kMinWidthT + kWidth * 5) * cos(rad) * v; + poly[2].X = x2 + (kMinWidthT + kWidth * 5) * sin(rad) * v; + poly[2].Y = y2 - (kMinWidthT + kWidth * 5) * cos(rad) * v; + poly[3].X = x2 + (kMinWidthT - 1) * sin(rad) * v - kMinWidthT * cos(rad) * v; + poly[3].Y = y2 - (kMinWidthT - 1) * cos(rad) * v - kMinWidthT * sin(rad) * v; + icPolygon(poly, 4); + } + + if(a1 == 22){ //SHIKAKU MIGIUE UROKO NANAME DEMO MASSUGU MUKI + poly3[0].X = x1 - kMinWidthT; + poly3[0].Y = y1 - kMinWidthY; + poly3[1].X = x1; + poly3[1].Y = y1 - kMinWidthY - kWidth; + poly3[2].X = x1 + kMinWidthT + kWidth; + poly3[2].Y = y1 + kMinWidthY; + poly3[3].X = x1 + kMinWidthT; + poly3[3].Y = y1 + kMinWidthT; + poly3[4].X = x1 - kMinWidthT; + poly3[4].Y = y1; + icPolygon(poly3, 5); + } + + XX = sin(rad) * v; + XY = cos(rad) * v * -1; + YX = cos(rad) * v; + YY = sin(rad) * v; + + if(a1 == 0){ //beginning of the storke + poly2[0].X = x1 + kMinWidthT * XX + (kMinWidthY * 0.5) * YX; + poly2[0].Y = y1 + kMinWidthT * XY + (kMinWidthY * 0.5) * YY; + poly2[1].X = x1 + (kMinWidthT + kMinWidthT * 0.5) * XX + (kMinWidthY * 0.5 + kMinWidthY) * YX; + poly2[1].Y = y1 + (kMinWidthT + kMinWidthT * 0.5) * XY + (kMinWidthY * 0.5 + kMinWidthY) * YY; + poly2[2].X = x1 + kMinWidthT * XX + (kMinWidthY * 0.5 + kMinWidthY * 2) * YX; + poly2[2].Y = y1 + kMinWidthT * XY + (kMinWidthY * 0.5 + kMinWidthY * 2) * YY; + icPolygon(poly2, 3); + } + } + } + } + else{ //gothic + if(tx1 == tx2){ //if TATE stroke, use y-axis + if(ty1 > ty2){ + x1 = tx2; + y1 = ty2; + x2 = tx1; + y2 = ty1; + a1 = ta2; + a2 = ta1; + } + else{ + x1 = tx1; + y1 = ty1; + x2 = tx2; + y2 = ty2; + a1 = ta1; + a2 = ta2; + } + + if(a1 % 10 == 2){ y1 = y1 - kWidth; } + if(a2 % 10 == 2){ y2 = y2 + kWidth; } + if(a1 % 10 == 3){ y1 = y1 - kWidth * kKakato; } + if(a2 % 10 == 3){ y2 = y2 + kWidth * kKakato; } + + poly[0].X = x1 - kWidth; + poly[0].Y = y1; + poly[1].X = x2 - kWidth; + poly[1].Y = y2; + poly[2].X = x2 + kWidth; + poly[2].Y = y2; + poly[3].X = x1 + kWidth; + poly[3].Y = y1; + + icPolygon(poly, 4); + } + else if(ty1 == ty2){ //if YOKO stroke, use x-axis + if(tx1 > tx2){ + x1 = tx2; + y1 = ty2; + x2 = tx1; + y2 = ty1; + a1 = ta2; + a2 = ta1; + } + else{ + x1 = tx1; + y1 = ty1; + x2 = tx2; + y2 = ty2; + a1 = ta1; + a2 = ta2; + } + if(a1 % 10 == 2){ x1 = x1 - kWidth; } + if(a2 % 10 == 2){ x2 = x2 + kWidth; } + if(a1 % 10 == 3){ x1 = x1 - kWidth * kKakato; } + if(a2 % 10 == 3){ x2 = x2 + kWidth * kKakato; } + + poly[0].X = x1; + poly[0].Y = y1 - kWidth; + poly[1].X = x2; + poly[1].Y = y2 - kWidth; + poly[2].X = x2; + poly[2].Y = y2 + kWidth; + poly[3].X = x1; + poly[3].Y = y1 + kWidth; + + icPolygon(poly, 4); + } + else{ //for others, use x-axis + if(tx1 > tx2){ + x1 = tx2; + y1 = ty2; + x2 = tx1; + y2 = ty1; + a1 = ta2; + a2 = ta1; + } + else{ + x1 = tx1; + y1 = ty1; + x2 = tx2; + y2 = ty2; + a1 = ta1; + a2 = ta2; + } + rad = atan((double)(y2 - y1) / (double)(x2 - x1)); + if(a1 % 10 == 2){ + x1 = x1 - kWidth * cos(rad); + y1 = y1 - kWidth * sin(rad); + } + if(a2 % 10 == 2){ + x2 = x2 + kWidth * cos(rad); + y2 = y2 + kWidth * sin(rad); + } + if(a1 % 10 == 3){ + x1 = x1 - kWidth * cos(rad) * kKakato; + y1 = y1 - kWidth * sin(rad) * kKakato; + } + if(a2 % 10 == 3){ + x2 = x2 + kWidth * cos(rad) * kKakato; + y2 = y2 + kWidth * sin(rad) * kKakato; + } + + //SUICHOKU NO ICHI ZURASHI HA sin TO cos NO IREKAE + x-axis MAINASU KA + poly[0].X = x1 + sin(rad) * kWidth; + poly[0].Y = y1 - cos(rad) * kWidth; + poly[1].X = x2 + sin(rad) * kWidth; + poly[1].Y = y2 - cos(rad) * kWidth; + poly[2].X = x2 - sin(rad) * kWidth; + poly[2].Y = y2 + cos(rad) * kWidth; + poly[3].X = x1 - sin(rad) * kWidth; + poly[3].Y = y1 + cos(rad) * kWidth; + + icPolygon(poly, 4); + } + } +} diff --git a/kagecgi/kagecgi.c b/kagecgi/kagecgi.c new file mode 100755 index 0000000..6fce983 --- /dev/null +++ b/kagecgi/kagecgi.c @@ -0,0 +1,193 @@ +//kagecgi.c +// + +#include +#include +#include +#include +#include "kage.h" +#include "kagecgi.h" + +int main(int argc, char *argv[]){ + GString *tmp1, *tmp2, *test1, *test2, *filename; + FILE *err, *fp; + char errbuf[errorFileSize]; + char *pos, *cur; + int dummy; + int i; + + dummy = initDB(); + + //set default + kShotai = kMincho; +// kShotai = kGothic; +// kDesign = 0; //jp + kSize = 200; + kType = 0; //png + kInput = 0; //ids or direct + kResultText = g_string_new(""); + kMode = 0; + + //set some param by request +// tmp1 = g_string_new((gchar *)argv[1]); + tmp1 = g_string_new((gchar *)getenv("QUERY_STRING")); + pos = tmp1->str; + + //separate token + if(tmp1->len != 0){ + while(1){ + cur = strchr(pos, '&'); + tmp2 = g_string_new(pos); + if(cur != NULL) g_string_set_size(tmp2, cur - pos); + //got request string +// if(strncmp(tmp2->str, "design=jp", 9) == 0) kDesign = 0; +// else if(strncmp(tmp2->str, "design=cs", 9) == 0) kDesign = 10; +// else if(strncmp(tmp2->str, "design=ct", 9) == 0) kDesign = 11; +// else if(strncmp(tmp2->str, "design=kr", 9) == 0) kDesign = 20; +// else if(strncmp(tmp2->str, "design=vn", 9) == 0) kDesign = 30; +// else if(strncmp(tmp2->str, "design=un", 9) == 0) kDesign = 40; +// else if(strncmp(tmp2->str, "shotai=mincho", 13) == 0) kShotai = kMincho; + if(strncmp(tmp2->str, "shotai=mincho", 13) == 0) kShotai = kMincho; + else if(strncmp(tmp2->str, "shotai=gothic", 13) == 0) kShotai = kGothic; + else if(strncmp(tmp2->str, "shotai=skeleton", 15) == 0) kShotai = kGothic; + else if(strncmp(tmp2->str, "type=png", 8) == 0) kType = 0; + else if(strncmp(tmp2->str, "type=svg", 8) == 0) kType = 1; + else if(strncmp(tmp2->str, "type=eps", 8) == 0) kType = 2; + else if(strncmp(tmp2->str, "type=raw", 8) == 0) kType = 3; + else if(strncmp(tmp2->str, "input=ids", 9) == 0) kInput = 0; + else if(strncmp(tmp2->str, "input=directwithadjust", 22) == 0) kInput = 2; + else if(strncmp(tmp2->str, "input=direct", 12) == 0) kInput = 1; + else if(strncmp(tmp2->str, "size=24", 7) == 0) kSize = 24; + else if(strncmp(tmp2->str, "size=200", 8) == 0) kSize = 200; + else test1 = g_string_new(tmp2->str); + if(cur == NULL) break; + pos = cur + 1; + } + } + else{ // redirected request + kInput = 0; + tmp1 = g_string_new((gchar *)getenv("REDIRECT_URL")); + pos = tmp1->str; + while(1){ + cur = strchr(pos, '/'); + tmp2 = g_string_new(pos); + if(cur != NULL) g_string_set_size(tmp2, cur - pos); + //got request string +// if(strncmp(tmp2->str, "jp", 2) == 0) kDesign = 0; +// else if(strncmp(tmp2->str, "cs", 2) == 0) kDesign = 10; +// else if(strncmp(tmp2->str, "ct", 2) == 0) kDesign = 11; +// else if(strncmp(tmp2->str, "kr", 2) == 0) kDesign = 20; +// else if(strncmp(tmp2->str, "vn", 2) == 0) kDesign = 30; +// else if(strncmp(tmp2->str, "un", 2) == 0) kDesign = 40; +// else if(strncmp(tmp2->str, "mincho", 6) == 0) kShotai = kMincho; + if(strncmp(tmp2->str, "mincho", 6) == 0) kShotai = kMincho; + else if(strncmp(tmp2->str, "gothic", 6) == 0) kShotai = kGothic; + else if(strncmp(tmp2->str, "skeleton", 8) == 0) kShotai = kGothic; + else if(strncmp(tmp2->str, "v0.4", 4) == 0); + else test1 = g_string_new(tmp2->str); + if(cur == NULL) break; + pos = cur + 1; + } + if(strncmp(test1->str + test1->len - 4, ".png", 4) == 0) kType = 0; + if(strncmp(test1->str + test1->len - 4, ".svg", 4) == 0) kType = 1; + if(strncmp(test1->str + test1->len - 4, ".eps", 4) == 0) kType = 2; + if(strncmp(test1->str + test1->len - 4, ".raw", 4) == 0) kType = 3; + g_string_set_size(test1, test1->len - 4); + } + + //clear result buffer + test2 = g_string_new(""); + if(kType == 2){ + g_string_append(kResultText, "%!PS-Adobe-3.0 EPSF-3.0\n"); + g_string_append(kResultText, "%%BoundingBox: 0 -208 1024 816\n"); + g_string_append(kResultText, "%%Pages: 0\n"); + g_string_append(kResultText, "%%Title: "); + g_string_append(kResultText, test1->str); + g_string_append(kResultText, "\n"); + g_string_append(kResultText, "%%Creator: KAGE System\n"); + g_string_append(kResultText, "%%CreationDate: 00:00 1-1-2004\n"); + g_string_append(kResultText, "%%EndComments\n"); + g_string_append(kResultText, "%%EndProlog\n"); + g_string_append(kResultText, "%%Page \""); + g_string_append(kResultText, test1->str); + g_string_append(kResultText, "\" 1\n"); + g_string_append(kResultText, "newpath\n"); + } + kageCanvas = initPng(canvasWidth, canvasHeight); + if(kInput == 0) generateGlyph(test1, test2); + else{ + convert99(test1, test2); + // g_string_append(test2, test1->str); + } + + if(kType == 0){ //png(image) + if(test2->len != 0){ + if(kInput != 1){ //0 and 2 + test2 = CalcSizes(test2, 1); + } + DrawBox(); + drawGlyph(test2, 0); + //output to file + filename = g_string_new(pngFilePath); +// if(kDesign == 0) g_string_append(filename, "jp/"); +// else if(kDesign == 10) g_string_append(filename, "cs/"); +// else if(kDesign == 11) g_string_append(filename, "ct/"); +// else if(kDesign == 20) g_string_append(filename, "kr/"); +// else if(kDesign == 30) g_string_append(filename, "vn/"); +// else if(kDesign == 40) g_string_append(filename, "un/"); + if(kShotai == kMincho) g_string_append(filename, "mincho/"); + else if(kShotai == kGothic) g_string_append(filename, "gothic/");//skeleton?? + g_string_append(filename, test1->str); + g_string_append(filename, ".png"); + +//skip for adjustment mode +// fp = fopen(filename->str, "w"); +// writePng(pngWidth, pngHeight, kageCanvas, fp); +// fclose(fp); + //output to stdout + fprintf(stdout, "Content-type: image/png\n\n"); + writePng(pngWidth, pngHeight, kageCanvas, stdout); + //done + closePng(pngWidth, pngHeight, kageCanvas); + } + else{ + err = fopen("error.png", "r"); + fread(errbuf, sizeof(char), errorFileSize, err); + // printf("An error occurred.\r\n"); + fprintf(stdout, "Content-type: image/png\n\n"); + fwrite(errbuf, sizeof(char), errorFileSize, stdout); + fclose(err); + } + } + else if(kType == 1){ //svg(vector graphics) + } + else if(kType == 2){ //eps(vector graphics) + if(test2->len != 0){ + test2 = CalcSizes(test2, 1); + kMode = 1; + drawGlyph(test2, 0); + g_string_append(kResultText, "fill\n"); + g_string_append(kResultText, "%%EOF\n"); + fprintf(stdout, "Content-type: application/postscript\n\n"); + fprintf(stdout, "%s", kResultText->str); + } + else{ + fprintf(stdout, "Content-type: text/plain\n\n"); + fprintf(stdout, "An error occurred."); + } + } + else{ //raw(text) + if(test2->len != 0){ + fprintf(stdout, "Content-type: text/plain\n\n"); + fprintf(stdout, "result=%s", test2->str); + } + else{ + fprintf(stdout, "Content-type: text/plain\n\n"); + fprintf(stdout, "result=nodata"); + } + } + dummy = closeDB(); + + return 0; +} + diff --git a/kagecgi/kagecgi.h b/kagecgi/kagecgi.h new file mode 100755 index 0000000..36dad00 --- /dev/null +++ b/kagecgi/kagecgi.h @@ -0,0 +1,85 @@ +//kagecgi.h +// + +#include +//#include + +#include +#include +#include "kage.h" + +#ifndef _KAGECGI_H_ +#define _KAGECGI_H_ + +// define for localhost environment +#define errorFileSize 4009 +#define errorFileName "error.png" +#define pngFilePath "/var/www/fontsjp/v0.4/" +#define databaseFileName "../../kagedb/wiki" + +#define kBaseline 188 +#define pngWidth 200 +#define pngHeight 200 +#define canvasWidth 400 +#define canvasHeight 400 + +#define min(x1,x2) ((x1) > (x2))? (x2):(x1) +#define max(x1,x2) ((x1) > (x2))? (x1):(x2) + +DB *kDatabase; + +FILE *debug; + +png_bytepp kageCanvas; + +int kDesign; +int kSize; +int kType; +int kInput; +GString *kResultText; +int kMode; + +void generateGlyph(const GString *in, GString *out); +void searchPartsData(const GString *in, GString *out); +void searchAliasData(const GString *in, GString *out); +void searchCacheData(const GString *in, GString *out); +void doCombine(const GString *in, GString *out); +void drawGlyph(const GString *in, const int mode); + +int isIDS(const GString *in); +void divideInto2(const GString *in, GString *partIDS1, GString *partIDS3); +void divideInto3(const GString *in, GString *partIDS1, GString *partIDS2, GString *partIDS3); +void addStrokeWithTransform(const GString *stroke, const int num, const int *tf, GString *out, int mode); +void convertArray(int *buf, GString *out, int size, int mode); +int * convertStroke(const char *in, int *a, int *size); +void convert99(const GString *in, GString *out); +void convert99calc(const char *in, GString *out); + +void DotsWidth(int *dlx, int *drx); +void DotsHeight(int *dly, int *dry); +void PartsWidth(const GString *in, int *lx, int *rx); +void PartsHeight(const GString *in, int *ly, int *ry); +GString * CalcSizes(const GString *in, int mode); +void DrawBox(); +void CalcOptions(const GString *in, int *mitsudo, int *flag, double *yoko, double *tate); +void DoDrawParts(const GString *in, const int lx1, const double rf1, const int ly1, const double rfy1); +void DoDrawMixFont(const GString *in1, const int lx1, const double rf1, const GString *in2, const int lx2, const double rf2, const int ly1, const double rfy1, const int ly2, const double rfy2); + +void combineYoko2(const GString *parts1, const GString *parts3, int *result); +void combineYoko3(const GString *parts1, const GString *parts2, const GString *parts3, int *result); +void combineTate2(const GString *parts1, const GString *parts3, int *result); +void combineTate3(const GString *parts1, const GString *parts2, const GString *parts3, int *result); +void combineHame2(const GString *parts1, const GString *parts3, int *result); + +int initDB(); +int closeDB(); +void searchPartsData(const GString *in, GString *out); +void searchAliasData(const GString *in, GString *out); + +png_bytepp initPng(int width, int height); +int closePng(int width, int height, png_bytepp canvas); +int writePng(int width, int height, png_bytepp image, FILE *fp); + +void fillPolygon(struct kPoint *p, int number, int col, unsigned char **image); + +#endif diff --git a/kagecgi/kagechar.c b/kagecgi/kagechar.c new file mode 100755 index 0000000..daa2d25 --- /dev/null +++ b/kagecgi/kagechar.c @@ -0,0 +1,397 @@ +//kagechar.c +// + +#include +#include +#include "kagecgi.h" +#include "kage.h" + +int isIDS(const GString *in){ + //check IDC "u2ff*" + if(strncmp(in->str, "u2ff", 4) == 0){ + //check the last char + if('0' <= (in->str)[4] && (in->str)[4] <= 'a') return TRUE; + } + return FALSE; +} + +void divideInto2(const GString *in, GString *partIDS1, GString *partIDS3){ + GString *buffer[16]; + char tmp[kMaxIDCLength + 1]; + int i, counter, pointer, flag; + + g_string_set_size(partIDS1, 0); + + counter = 0; + pointer = 0; + for(i = 0; i < in->len; i++){ + if((in->str)[i] == '.'){ + strncpy(tmp, (in->str) + pointer, i - pointer); + tmp[i - pointer] = '\0'; + buffer[counter] = g_string_new(tmp); + counter++; + pointer = i + 1; + } + } + strncpy(tmp, (in->str) + pointer, i - pointer); + tmp[i - pointer] = '\0'; + buffer[counter] = g_string_new(tmp); + counter++; + + //reject over-length of IDS + if(counter > kMaxIDSSequenceLength) return; + + //1st scan + pointer = 1; + flag = 0; + while(flag >= 0 && pointer < counter){ + g_string_append(partIDS1, (buffer[pointer])->str); + g_string_append(partIDS1, "."); + if(strncmp((buffer[pointer])->str, "u2ff", 4) == 0){ + switch (((buffer[pointer])->str)[4]){ + case '0': + case '1': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case 'a': + case 'b': + flag++; + break; + case '2': + case '3': + flag = flag + 2; + break; + } + } + else flag--; + pointer++; + } + g_string_erase(partIDS1, partIDS1->len - 1, 1); + + //2nd scan + flag = 0; + while(flag >= 0 && pointer < counter){ + g_string_append(partIDS3, (buffer[pointer])->str); + g_string_append(partIDS3, "."); + if(strncmp((buffer[pointer])->str, "u2ff", 4) == 0){ + switch (((buffer[pointer])->str)[4]){ + case '0': + case '1': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case 'a': + case 'b': + flag++; + break; + case '2': + case '3': + flag = flag + 2; + break; + } + } + else flag--; + pointer++; + } + g_string_erase(partIDS3, partIDS3->len - 1, 1); +} + +void divideInto3(const GString *in, GString *partIDS1, GString *partIDS2, GString *partIDS3){ + GString *buffer[16]; + char tmp[kMaxIDCLength + 1]; + int i, counter, pointer, flag; + + g_string_set_size(partIDS1, 0); + + counter = 0; + pointer = 0; + for(i = 0; i < in->len; i++){ + if((in->str)[i] == '.'){ + strncpy(tmp, (in->str) + pointer, i - pointer); + tmp[i - pointer] = '\0'; + buffer[counter] = g_string_new(tmp); + counter++; + pointer = i + 1; + } + } + strncpy(tmp, (in->str) + pointer, i - pointer); + tmp[i - pointer] = '\0'; + buffer[counter] = g_string_new(tmp); + counter++; + + //reject over-length of IDS + if(counter > kMaxIDSSequenceLength) return; + + //1st scan + pointer = 1; + flag = 0; + while(flag >= 0 && pointer < counter){ + g_string_append(partIDS1, (buffer[pointer])->str); + g_string_append(partIDS1, "."); + if(strncmp((buffer[pointer])->str, "u2ff", 4) == 0){ + switch (((buffer[pointer])->str)[4]){ + case '0': + case '1': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case 'a': + case 'b': + flag++; + break; + case '2': + case '3': + flag = flag + 2; + break; + } + } + else flag--; + pointer++; + } + g_string_erase(partIDS1, partIDS1->len - 1, 1); + + //2nd scan + flag = 0; + while(flag >= 0 && pointer < counter){ + g_string_append(partIDS2, (buffer[pointer])->str); + g_string_append(partIDS2, "."); + if(strncmp((buffer[pointer])->str, "u2ff", 4) == 0){ + switch (((buffer[pointer])->str)[4]){ + case '0': + case '1': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case 'a': + case 'b': + flag++; + break; + case '2': + case '3': + flag = flag + 2; + break; + } + } + else flag--; + pointer++; + } + g_string_erase(partIDS2, partIDS2->len - 1, 1); + + //3rd scan + flag = 0; + while(flag >= 0 && pointer < counter){ + g_string_append(partIDS3, (buffer[pointer])->str); + g_string_append(partIDS3, "."); + if(strncmp((buffer[pointer])->str, "u2ff", 4) == 0){ + switch (((buffer[pointer])->str)[4]){ + case '0': + case '1': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case 'a': + case 'b': + flag++; + break; + case '2': + case '3': + flag = flag + 2; + break; + } + } + else flag--; + pointer++; + } + g_string_erase(partIDS3, partIDS3->len - 1, 1); +} + +void addStrokeWithTransform(const GString *stroke, const int num, const int *tf, GString *out, int mode){ + int *buf, i, size; + GString *tmp; + + tmp = g_string_new(""); + buf = convertStroke(stroke->str, buf, &size); + + for(i = 0; i < size; i++){ + if(buf[i * 11 + 0] != 0 && buf[i * 11 + 0] != 99){ + buf[i * 11 + 3] = + tf[(num - 1) * 4 + 0] + buf[i * 11 + 3] * (tf[(num - 1) * 4 + 2] - tf[(num - 1) * 4 + 0]) / pngWidth; + buf[i * 11 + 5] = + tf[(num - 1) * 4 + 0] + buf[i * 11 + 5] * (tf[(num - 1) * 4 + 2] - tf[(num - 1) * 4 + 0]) / pngWidth; + buf[i * 11 + 7] = + tf[(num - 1) * 4 + 0] + buf[i * 11 + 7] * (tf[(num - 1) * 4 + 2] - tf[(num - 1) * 4 + 0]) / pngWidth; + buf[i * 11 + 9] = + tf[(num - 1) * 4 + 0] + buf[i * 11 + 9] * (tf[(num - 1) * 4 + 2] - tf[(num - 1) * 4 + 0]) / pngWidth; + buf[i * 11 + 4] = + tf[(num - 1) * 4 + 1] + buf[i * 11 + 4] * (tf[(num - 1) * 4 + 3] - tf[(num - 1) * 4 + 1]) / pngHeight; + buf[i * 11 + 6] = + tf[(num - 1) * 4 + 1] + buf[i * 11 + 6] * (tf[(num - 1) * 4 + 3] - tf[(num - 1) * 4 + 1]) / pngHeight; + buf[i * 11 + 8] = + tf[(num - 1) * 4 + 1] + buf[i * 11 + 8] * (tf[(num - 1) * 4 + 3] - tf[(num - 1) * 4 + 1]) / pngHeight; + buf[i * 11 + 10] = + tf[(num - 1) * 4 + 1] + buf[i * 11 + 10] * (tf[(num - 1) * 4 + 3] - tf[(num - 1) * 4 + 1]) / pngHeight; + } + } + convertArray(buf, tmp, size, mode); + if(out->len != 0) g_string_append(out, "$"); + g_string_append(out, tmp->str); + + free((void *)buf); +} + +void convertArray(int *buf, GString *out, int size, int mode){ + int i; + char tmp[kMaxStrokeDataLength]; + + for(i = 0; i < size; i++){ + if(!(mode == 1 && (buf[i * 11 + 0] == 0 || buf[i * 11 + 0] == 99))){ + sprintf(tmp, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d$", + buf[i * 11 + 0], + buf[i * 11 + 1], + buf[i * 11 + 2], + buf[i * 11 + 3], + buf[i * 11 + 4], + buf[i * 11 + 5], + buf[i * 11 + 6], + buf[i * 11 + 7], + buf[i * 11 + 8], + buf[i * 11 + 9], + buf[i * 11 + 10]); + g_string_append(out, tmp); + } + } + g_string_erase(out, (out->len - 1), 1); +} + +int * convertStroke(const char *in, int *a, int *size){ + int i, counter, pointer; + int a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10; + char tmp[kMaxStrokeDataLength + 1]; + + a = (int *)malloc(0); + counter = 0; + pointer = 0; + for(i = 0; i < strlen(in); i++){ + if(in[i] == '$'){ + strncpy(tmp, &in[pointer], i - pointer); + tmp[i - pointer] = '\0'; + a = (int *)realloc(a, sizeof(int) * 11 * (counter + 1)); + sscanf(tmp, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d", + &a0,&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10); + a[counter * 11 + 0] = a0; + a[counter * 11 + 1] = a1; + a[counter * 11 + 2] = a2; + a[counter * 11 + 3] = a3; + a[counter * 11 + 4] = a4; + a[counter * 11 + 5] = a5; + a[counter * 11 + 6] = a6; + a[counter * 11 + 7] = a7; + a[counter * 11 + 8] = a8; + a[counter * 11 + 9] = a9; + a[counter * 11 + 10] = a10; + counter++; + pointer = i + 1; + } + } + strncpy(tmp, &in[pointer], i - pointer); + tmp[i - pointer] = '\0'; + a = (int *)realloc(a, sizeof(int) * 11 * (counter + 1)); + sscanf(tmp, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d", + &a0,&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10); + a[counter * 11 + 0] = a0; + a[counter * 11 + 1] = a1; + a[counter * 11 + 2] = a2; + a[counter * 11 + 3] = a3; + a[counter * 11 + 4] = a4; + a[counter * 11 + 5] = a5; + a[counter * 11 + 6] = a6; + a[counter * 11 + 7] = a7; + a[counter * 11 + 8] = a8; + a[counter * 11 + 9] = a9; + a[counter * 11 + 10] = a10; + counter++; + *(size) = counter; + return a; +} + +void convert99(const GString *in, GString *out){ + int i, pointer; + char tmp[kMaxStrokeDataLength + 1]; + GString *buf; + + g_string_set_size(out, 0); + buf = g_string_new(""); + pointer = 0; + for(i = 0; i < in->len; i++){ + if((in->str)[i] == '$'){ + strncpy(tmp, in->str + pointer, i - pointer); + tmp[i - pointer] = '\0'; + if(strncmp(tmp, "99:", 3) == 0){ + convert99calc(tmp, buf); + if(buf->len == 0){ + g_string_set_size(out, 0); + return; + } + g_string_append(out, buf->str); + } + else g_string_append(out, tmp); + g_string_append(out, "$"); + + pointer = i + 1; + } + } + strncpy(tmp, in->str + pointer, i - pointer); + tmp[i - pointer] = '\0'; + if(strncmp(tmp, "99:", 3) == 0){ + convert99calc(tmp, buf); + if(buf->len == 0){ + g_string_set_size(out, 0); + return; + } + g_string_append(out, buf->str); + } + else g_string_append(out, tmp); +} + +void convert99calc(const char *in, GString *out){ + GString *buf1, *buf2; + int a1,x1,y1,x2,y2,option,option2; + char pname[kMaxStrokeDataLength]; + int tf[12]; + char *end; + + g_string_set_size(out, 0); + buf2 = g_string_new(""); + + //get parts data + sscanf(in, "%d:%d:%d:%d:%d:%d:%d:%s", + &a1,&option,&option2,&x1,&y1,&x2,&y2,pname); + //end = strchr(pname, ':'); + //*end = '\0'; + buf1 = g_string_new(pname); + generateGlyph(buf1, buf2); + if(buf2->len == 0) return; + + //convert + tf[0] = x1; + tf[1] = y1; + tf[2] = x2; + tf[3] = y2; + addStrokeWithTransform(buf2, 1, tf, out, 1); +} diff --git a/kagecgi/kagecomb.c b/kagecgi/kagecomb.c new file mode 100755 index 0000000..d90f0e0 --- /dev/null +++ b/kagecgi/kagecomb.c @@ -0,0 +1,400 @@ +//kagecomb.c +// +#include +#include +#include +#include "kagecgi.h" +#include "kage.h" + +void combineYoko2(const GString *parts1, const GString *parts3, int *result){ + int f, g, h, i, j, k, l; + int flg_boxL, flg_boxR; + int Xside, YsideLa, YsideLb, YsideRa, YsideRb, YheightL, YnanameL, YsmallL; + int pxL, pxR, pyL, pyR; + double prL, prR, pryL, pryR, rL, rR, rTemp; + int lxL, rxL, lxR, rxR; + int dlyL, dryL, dlyR, dryR; + int chk_y1, chk_y2; + int mitsuL, mitsuR; + double yokoL, tateL, yokoR, tateR; + int *buf, strokes; + int tempShotai; + + //initialize + pxL = 0; + pyL = 0; + prL = 1.0; + pryL = 1.0; + pxR = 0; + pyR = 0; + prR = 1.0; + pryR = 1.0; + + YsideLa = 0; + YsideLb = 0; + YsideRa = 0; + YsideRb = 0; + YnanameL = 0; + YheightL = pngWidth * 0.9; + + tempShotai = kShotai; + kShotai = kGothic; + + CalcOptions(parts1, &mitsuL, &flg_boxL, &yokoL, &tateL); + CalcOptions(parts3, &mitsuR, &flg_boxR, &yokoR, &tateR); + + //left parts Y-axis processing #1 + //if its upper and bottom are flat + if(flg_boxL % 8 / 4 != 0) YsideLa++; + if(flg_boxL % 16 / 8 != 0) YsideLb++; + + //if its goes right-up + if(flg_boxL % 1024 / 512 == 0){ + j = 0; + buf = convertStroke(parts1->str, buf, &strokes); + for(i = 0; i < strokes; i++) if(buf[i * 11 + 0] / 10 == 1) j++; + free(buf); + l = 0; + if(j != 0){ + YsideLb++; + YnanameL++; + } + } + YheightL = YheightL - (YsideLa + YsideLb) * 2 * kWidth; + + //left parts Y-axis processing #2 + YsmallL = 0; + if(flg_boxL % 1024 / 512 == 0){ + YsmallL = 1; + if(flg_boxL % 16 / 8 != 0 && flg_boxL % 8 / 4 != 0 && tateL <= 4) YheightL = (double)YheightL * (max(0.65, tateL * 0.22)); + else if(flg_boxL % 16 / 8 != 0 && tateL <= 3) YheightL = (double)YheightL * 0.8; + else if(YnanameL != 0 && flg_boxL % 8 / 4 != 0 && tateL <= 4) YheightL = (double)YheightL * (max(0.65, tateL * 0.22)); + else if(YnanameL != 0 && tateL <= 3) YheightL = (double)YheightL * 0.8; + else YsmallL = 0; + } + + //left parts Y-axis processing #3 + DoDrawParts(parts1, pxL, prL, pyL, pryL); + DotsHeight(&dlyL, &dryL); + pryL = (double)YheightL / (dryL - dlyL); + + if(YsmallL != 0){ + if(flg_boxL % 8 / 4 != 0) pyL = kBaseline - (double)pngWidth * 0.9 + 6 * kWidth - dlyL * pryL; + else pyL = kBaseline - (double)pngWidth * 0.9 + 2 * kWidth - dlyL * pryL; + } + else{ + if(flg_boxL % 16 / 8 != 0 || YnanameL != 0) pyL = kBaseline - 2 * kWidth - dryL * pryL; + else pyL = kBaseline - dryL * pryL; + } + + //right parts Y-axis processing #1 + if(flg_boxR % 8 / 4 != 0) YsideRa++; + if(flg_boxR % 16 / 8 != 0) YsideRb++; + + DoDrawParts(parts3, pxR, prR, pyR, pryR); + DotsHeight(&dlyR, &dryR); + + if(flg_boxR % 512 / 256 != 0 && flg_boxR % 1024 / 512 == 0){ + pryR = pngWidth * 0.9 * 0.8 / (dryR - dlyR); + pyR = kBaseline - pngWidth * 0.9 + 6 * kWidth - dlyR * pryR; + } + else{ + pryR = ((double)pngWidth * 0.9 - (YsideRa + YsideRb) * 2 * kWidth) / (dryR - dlyR); + pyR = kBaseline - dryR * pryR; + if(flg_boxR % 16 / 8 != 0) pyR = pyR - 2 * kWidth; + } + + //calculate ratio + rL = yokoL; + rR = yokoR; + + if(flg_boxL % 2 / 1 != 0) rL = rL * 0.7; + if(flg_boxL % 4 / 2 != 0) rL = rL * 0.7; + if(flg_boxR % 2 / 1 != 0) rR = rR * 0.7; + if(flg_boxR % 4 / 2 != 0) rR = rR * 0.7; + + rL = pow(rL, 0.6); + rR = pow(rR, 0.6); + + rR = rR * 1.05; + + rTemp = rL + rR; + rL = rL / rTemp; + rR = rR / rTemp; + +// if(r < 0.3) r = 0.3; +// else if(r > 0.7) r = 0.7; + + prL = rL; + prR = rR; + + //calculate width of each parts #1 + Xside = 0; + if(flg_boxL % 2 / 1 != 0) Xside++; + if(flg_boxR % 4 / 2 != 0) Xside++; + +// DrawBox(); +// drawGlyph(parts1, 1); +// DotsWidth(&lxL, &rxL); +// DrawBox(); +// drawGlyph(parts3, 1); +// DotsWidth(&lxR, &rxR); + PartsWidth(parts1, &lxL, &rxL); + PartsWidth(parts3, &lxR, &rxR); + g = 0; + + //calculate width of each parts #2 +// pxL = kWidth * 2 + (pngWidth - kWidth * 2 * 2) * prL * 0.5 - (lxL + rxL) / 2 * prL; +// pxR = kWidth * 2 + (pngWidth - kWidth * 2 * 2) * prL + kWidth * 2 * 2 + (pngWidth - kWidth * 2 * 2) * prR * 0.5 - (lxR + rxR) / 2 * prR; + pxL = pngWidth * prL * 0.5 - (lxL + rxL) / 2 * prL; + pxR = pngWidth * prL + kWidth * 4 + pngWidth * prR * 0.5 - (lxR + rxR) / 2 * prR; + + DoDrawMixFont(parts1, pxL, prL, parts3, pxR, prR, pyL, pryL, pyR, pryR); + + //count dots for check crossing over + DotsHeight(&chk_y1, &chk_y2); + k = 0; + for(i = 0; i < pngWidth * 1.1; i++){ + for(j = chk_y1; j <= chk_y2; j++){ + if(kageCanvas[j][i] == 0) k++; + } + } + l = k; + + //get close both parts + h = pxR; + while(k - l < kMixdot && g < kWidth * (kKasane + 4)){ + g = g + 2; + f = pxR - g; + DoDrawMixFont(parts1, pxL, prL, parts3, f, prR, pyL, pryL, pyR, pryR); + + l = 0; + for(i = 0; i < pngWidth * 1.1; i++){ + for(j = chk_y1; j <= chk_y2; j++){ + if(kageCanvas[j][i] == 0) l++; + } + } + } + pxR = f; + if(flg_boxR % 256 / 128 != 0) pxR = pxR + kWidth * 12; + if(flg_boxR % 64 / 32 != 0) pxR = pxR + kWidth * 8; + else if(k - l > pngWidth * 0.4) pxR = pxR + kWidth * 5; + else pxR = pxR + kWidth * 3; + + //set results + result[0] = pxL; + result[1] = pyL; + result[2] = pxL + pngWidth * prL; + result[3] = pyL + pngWidth * pryL; + result[8] = pxR; + result[9] = pyR; + result[10] = pxR + pngWidth * prR; + result[11] = pyR + pngWidth * pryR; + + kShotai = tempShotai; +} + +void combineYoko3(const GString *parts1, const GString *parts2, const GString *parts3, int *result){ + //not yet +} + +void combineTate2(const GString *parts1, const GString *parts3, int *result){ + int f, g, h, i, j, k, l; + int flg_boxL, flg_boxR; + int pxL, pxR, pyL, pyR; + double prL, prR, pryL, pryR, rL, rR, rTemp; + int lxL, rxL, lxR, rxR; + int lyL, ryL, lyR, ryR; + int dlxL, drxL, dlxR, drxR; + int chk_x1, chk_x2; + int mitsuL, mitsuR; + double yokoL, tateL, yokoR, tateR; + int *buf, strokes; + int tempShotai; + + //initialize + pxL = 0; + pyL = 0; + prL = 1.0; + pryL = 1.0; + pxR = 0; + pyR = 0; + prR = 1.0; + pryR = 1.0; + + tempShotai = kShotai; + kShotai = kGothic; + + CalcOptions(parts1, &mitsuL, &flg_boxL, &yokoL, &tateL); + CalcOptions(parts3, &mitsuR, &flg_boxR, &yokoR, &tateR); + + //calculate ratio + rL = tateL; + rR = tateR; + + if(flg_boxL % 8 / 4 != 0) rL = rL * 0.7; + if(flg_boxL % 16 / 8 != 0) rL = rL * 0.7; + if(flg_boxR % 8 / 4 != 0) rR = rR * 0.7; + if(flg_boxR % 16 / 8 != 0) rR = rR * 0.7; + + rL = pow(rL, 0.8); + rR = pow(rR, 0.8); + + rR = rR * 1.1; + + rTemp = rL + rR; + rL = rL / rTemp; + rR = rR / rTemp; + +// if(r < 0.3) r = 0.3; +// else if(r > 0.7) r = 0.7; + + pryL = rL; + pryR = rR; + + //calucurate size of X-axis + PartsWidth(parts1, &lxL, &rxL); + PartsWidth(parts3, &lxR, &rxR); + PartsHeight(parts1, &lyL, &ryL); + PartsHeight(parts3, &lyR, &ryR); + + //left parts + if(flg_boxL % 64 / 32 != 0){ + buf = convertStroke(parts1->str, buf, &strokes); + for(i = 0; i < strokes; i++){ + if(buf[i * 11 + 0] == 0) j = buf[i * 11 + 4]; // center line + } + k = max(j - lxL, rxL - j);// k : distance from center line + prL = (kSize * 0.9 * 0.5) / k; + if(k == j - lxL) pxL = 0; + else pxL = kSize * 0.5 - j * prL; + } + else if(flg_boxL % 2 / 1 != 0 && flg_boxL % 4 / 2 != 0 && flg_boxL % 32 / 16 == 0){ + prL = min(1.0, (double)yokoL * 0.1 + 0.5) - ((kWidth * 6) / (kSize * 0.9)); + DoDrawParts(parts1, pxL, prL, pyL, pryL); + DotsWidth(&dlxL, &drxL); + pxL = (kSize / 2 - (dlxL + drxL) / 2); + } + else if(flg_boxL % 128 / 64 != 0){ + prL = 0.77; + DoDrawParts(parts1, pxL, prL, pyL, pryL); + DotsWidth(&dlxL, &drxL); + pxL = (kSize / 2 - (dlxL + drxL) / 2); + } + else if(flg_boxL % 2 / 1 != 0 && flg_boxL % 32 / 16 == 0){ + prL = (kSize * 0.9 - kWidth * 4) / (rxL - lxL); + pxL = kWidth * 4; + } + else if(flg_boxL % 4 / 2 != 0 && flg_boxL % 32 / 16 == 0){ + prL = (kSize * 0.9 - kWidth * 4) / (rxL - lxL); + pxL = (kSize*0.05+kWidth*2) - lxL * prL; + } + + //right parts + if(flg_boxR % 64 / 32 != 0){ + buf = convertStroke(parts3->str, buf, &strokes); + for(i = 0; i < strokes; i++){ + if(buf[i * 11 + 0] == 0) j = buf[i * 11 + 4]; // center line + } + k = max(j - lxR, rxR - j);// k : distance from center line + prR = (kSize * 0.9 * 0.5) / k; + if(k == j - lxR) pxR = 0; + else pxR = kSize * 0.5 - j * prR; + } + else if(flg_boxR % 2 / 1 != 0 && flg_boxR % 4 / 2 != 0 && flg_boxR % 32 / 16 == 0){ + prR = min(1.0, (double)yokoR * 0.1 + 0.5) - ((kWidth * 6) / (kSize * 0.9)); + DoDrawParts(parts3, pxR, prR, pyR, pryR); + DotsWidth(&dlxR, &drxR); + pxR = (kSize / 2 - (dlxR + drxR) / 2); + } + else if(flg_boxR % 128 / 64 != 0){ + prR = 0.77; + DoDrawParts(parts3, pxR, prR, pyR, pryR); + DotsWidth(&dlxR, &drxR); + pxR = (kSize / 2 - (dlxR + drxR) / 2); + } + else if(flg_boxR % 2 / 1 != 0 && flg_boxR % 32 / 16 == 0){ + prR = (kSize * 0.9 - kWidth * 4) / (rxR - lxR); +// pxR = width * 4; + pxR = (kSize*0.05+kWidth*3) - lxR * prR; + } + else if(flg_boxR % 4 / 2 != 0 && flg_boxR % 32 / 16 == 0){ + prR = (kSize * 0.9 - kWidth * 4) / (rxR - lxR); +// pxR = (size*0.05+width*2) - lxR * prR; + pxR = (kSize*0.05+kWidth*1) - lxR * prR; + } + + g = 0; + + //calculate width of each parts + pyL = kWidth * 1.5 + (kSize - kWidth * 1.5 * 4) * pryL * 0.5 - (lyL + ryL) / 2 * pryL; + pyR = kWidth * 1.5 + (kSize - kWidth * 1.5 * 4) * pryL + kWidth * 1.5 * 2 + (kSize - kWidth * 1.5 * 4) * pryR * 0.5 - (lyR + ryR) / 2 * pryR; + + DoDrawMixFont(parts1, pxL, prL, parts3, pxR, prR, pyL, pryL, pyR, pryR); + + //count dots for check crossing over + DotsWidth(&chk_x1, &chk_x2); + k = 0; + for(i = 0; i < pngWidth * 1.1; i++){ + for(j = chk_x1; j <= chk_x2; j++){ + if(kageCanvas[i][j] == 0) k++; + } + } + l = k; + + //get close both parts + h = pyR; + while(k - l < kMixdot && g < kWidth * (kKasane + 4)){ + g = g + 2; + f = pyR - g; + DoDrawMixFont(parts1, pxL, prL, parts3, pxR, prR, pyL, pryL, f, pryR); + + l = 0; + for(i = 0; i < pngWidth * 1.1; i++){ + for(j = chk_x1; j <= chk_x2; j++){ + if(kageCanvas[i][j] == 0) l++; + } + } + } + pyR = f; + if(k - l > pngWidth * 0.4) pyR = pyR + kWidth * 5; + else pyR = pyR + kWidth * 3; + + //set results + result[0] = pxL; + result[1] = pyL; + result[2] = pxL + pngWidth * prL; + result[3] = pyL + pngWidth * pryL; + result[8] = pxR; + result[9] = pyR; + result[10] = pxR + pngWidth * prR; + result[11] = pyR + pngWidth * pryR; + + kShotai = tempShotai; +} + +void combineTate3(const GString *parts1, const GString *parts2, const GString *parts3, int *result){ + //not yet +} + +void combineHame2(const GString *parts1, const GString *parts3, int *result){ + int i; + int *buf, strokes; + + //set results + result[0] = 0; + result[1] = 0; + result[2] = 200; + result[3] = 200; + buf = convertStroke(parts1->str, buf, &strokes); + for(i = 0; i < strokes; i++){ + if(buf[i * 11 + 0] == 9){ + + result[8] = buf[i * 11 + 3]; + result[9] = buf[i * 11 + 4]; + result[10] = buf[i * 11 + 5]; + result[11] = buf[i * 11 + 6]; + } + } + //not yet +} diff --git a/kagecgi/kagedb.c b/kagecgi/kagedb.c new file mode 100755 index 0000000..21cd2ba --- /dev/null +++ b/kagecgi/kagedb.c @@ -0,0 +1,123 @@ +//kagedb.c +// + +#include +//#include + +#include +#include +#include "kagecgi.h" +#include "kage.h" + +int initDB(){ + kDatabase = dbopen(databaseFileName, O_RDWR|O_CREAT, 0666, DB_HASH, NULL); + return 0; +} + +int closeDB(){ + kDatabase->close(kDatabase); + return 0; +} + +void searchPartsData(const GString *in, GString *out){ + DBT dbkey, dbdata; + char *start, *end; + GString *temp, *temp2; + + //cut off the end '-0000' if 'in' end with it + temp = g_string_new(in->str); +// if(strncmp(temp->str + temp->len - 5, "-0000", 5) == 0) g_string_set_size(temp, temp->len - 5); + if((temp->str)[0] == 'u'){ + if(strncmp(temp->str + temp->len - 4, "-j00", 4) == 0) g_string_set_size(temp, temp->len - 4); + else if(strncmp(temp->str + temp->len - 4, "-g00", 4) == 0) g_string_set_size(temp, temp->len - 2); + else if(strncmp(temp->str + temp->len - 4, "-t00", 4) == 0) g_string_set_size(temp, temp->len - 2); + else if(strncmp(temp->str + temp->len - 4, "-k00", 4) == 0) g_string_set_size(temp, temp->len - 2); + else if(strncmp(temp->str + temp->len - 4, "-v00", 4) == 0) g_string_set_size(temp, temp->len - 2); + else if(strncmp(temp->str + temp->len - 4, "-u00", 4) == 0) g_string_set_size(temp, temp->len - 2); + } + + memset(&dbkey,0,sizeof(DBT)); + memset(&dbdata,0,sizeof(DBT)); + dbkey.data = temp->str; + dbkey.size = temp->len; + g_string_set_size(out, 0); + temp2 = g_string_new(""); + kDatabase->get(kDatabase, &dbkey, &dbdata, 0); + if(dbdata.size != 0){ + //first:search selected shotai + if(kShotai == kMincho) start = strstr(dbdata.data, ",mincho,"); + else start = strstr(dbdata.data, ",gothic,"); + if(start != NULL){ + start = strchr((start+8), ','); + if(start != NULL){ + start = strchr((start+1), ','); + if(start != NULL){ + end = strchr((start+1), ','); + if(end != NULL){ + g_string_append_len(temp2, (start+1), end - start - 2 + 1); + convert99(temp2, out); + return; + } + } + } + } + //second:search another shotai + if(kShotai == kMincho) start = strstr(dbdata.data, ",gothic,"); + else start = strstr(dbdata.data, ",mincho,"); + if(start != NULL){ + start = strchr((start+8), ','); + if(start != NULL){ + start = strchr((start+1), ','); + if(start != NULL){ + end = strchr((start+1), ','); + if(end != NULL){ + g_string_append_len(temp2, (start+1), end - start - 2 + 1); + convert99(temp2, out); + return; + } + } + } + } + } +} + +void searchAliasData(const GString *in, GString *out){ + DBT dbkey, dbdata; + char *start, *end; + GString *temp; + + //cut off the end '-0000' if 'in' end with it + temp = g_string_new(in->str); +// if(strncmp(temp->str + temp->len - 5, "-0000", 5) == 0) g_string_set_size(temp, temp->len - 5); + if((temp->str)[0] == 'u'){ + if(strncmp(temp->str + temp->len - 4, "-j00", 4) == 0) g_string_set_size(temp, temp->len - 4); + else if(strncmp(temp->str + temp->len - 4, "-g00", 4) == 0) g_string_set_size(temp, temp->len - 2); + else if(strncmp(temp->str + temp->len - 4, "-t00", 4) == 0) g_string_set_size(temp, temp->len - 2); + else if(strncmp(temp->str + temp->len - 4, "-k00", 4) == 0) g_string_set_size(temp, temp->len - 2); + else if(strncmp(temp->str + temp->len - 4, "-v00", 4) == 0) g_string_set_size(temp, temp->len - 2); + else if(strncmp(temp->str + temp->len - 4, "-u00", 4) == 0) g_string_set_size(temp, temp->len - 2); + } + + memset(&dbkey,0,sizeof(DBT)); + memset(&dbdata,0,sizeof(DBT)); + dbkey.data = temp->str; + dbkey.size = temp->len; + g_string_set_size(out, 0); + kDatabase->get(kDatabase, &dbkey, &dbdata, 0); + if(dbdata.size != 0){ + start = strstr(dbdata.data, ",linkto,"); + if(start != NULL){ + start = strchr((start+8), ','); + if(start != NULL){ + start = strchr((start+1), ','); + if(start != NULL){ + end = strchr((start+1), ','); + if(end != NULL){ + g_string_append_len(out, (start+1), end - start - 2 + 1); + } + } + } + } + } +} + diff --git a/kagecgi/kagedf.c b/kagecgi/kagedf.c new file mode 100755 index 0000000..079c432 --- /dev/null +++ b/kagecgi/kagedf.c @@ -0,0 +1,356 @@ +//kagedf.c +// +#include "kage.h" + +void dfDrawFont(int a1, int a2, int a3, + int x1, int y1, + int x2, int y2, + int x3, int y3, + int x4, int y4){ + int tx1, tx2, tx3, tx4, ty1, ty2, ty3, ty4, v; + double rad; + + if(kShotai == kMincho){ + switch(a1 % 100){ + case 0: + break; + case 1: + if(a3 == 4){ + if(x1 == x2){ + if(y1 < y2){ v = 1; } else{ v = -1; } + tx1 = x2; + ty1 = y2 - kMage * v; + } + else if(y1 == y2){ + if(x1 < x2){ v = 1; } else{ v = -1; } + tx1 = x2 - kMage * v; + ty1 = y2; + } + else{ + rad = atan((double)(y2 - y1) / (double)(x2 - x1)); + if(x1 < x2){ v = 1; } else{v = -1; } + tx1 = x2 - kMage * cos(rad) * v; + ty1 = y2 - kMage * sin(rad) * v; + } + cdDrawLine(x1, y1, tx1, ty1, a2, 1); + cdDrawCurve(tx1, ty1, x2, y2, x2 - kMage, y2, 1, 14); + } + else{ + cdDrawLine(x1, y1, x2, y2, a2, a3); + } + break; + case 2: + case 12: + if(a3 == 4){ + if(x2 == x3){ + tx1 = x3; + ty1 = y3 - kMage; + } + else if(y2 == y3){ + tx1 = x3 - kMage; + ty1 = y3; + } + else{ + rad = atan((double)(y3 - y2) / (double)(x3 - x2)); + if(x2 < x3){ v = 1; } else{ v = -1; } + tx1 = x3 - kMage * cos(rad) * v; + ty1 = y3 - kMage * sin(rad) * v; + } + cdDrawCurve(x1, y1, x2, y2, tx1, ty1, a2, 1); + cdDrawCurve(tx1, ty1, x3, y3, x3 - kMage, y3, 1, 14); + } + else if(a3 == 5){ + cdDrawCurve(x1, y1, x2, y2, x3, y3, a2, 15); + } + else{ + cdDrawCurve(x1, y1, x2, y2, x3, y3, a2, a3); + } + break; + case 3: + if(a3 == 5){ + if(x1 == x2){ + if(y1 < y2){ v = 1; } else{ v = -1; } + tx1 = x2; + ty1 = y2 - kMage * v; + } + else if(y1 == y2){ + if(x1 < x2){ v = 1; } else{ v = -1; } + tx1 = x2 - kMage * v; + ty1 = y2; + } + else{ + rad = atan((double)(y2 - y1) / (double)(x2 - x1)); + if(x1 < x2){ v = 1; } else{ v = -1; } + tx1 = x2 - kMage * cos(rad) * v; + ty1 = y2 - kMage * sin(rad) * v; + } + if(x2 == x3){ + if(y2 < y3){ v = 1; } else{ v = -1; } + tx2 = x2; + ty2 = y2 + kMage * v; + } + else if(y2 == y3){ + if(x2 < x3){ v = 1; } else { v = -1; } + tx2 = x2 + kMage * v; + ty2 = y2; + } + else{ + rad = atan((double)(y3 - y2) / (double)(x3 - x2)); + if(x2 < x3){ v = 1; } else{ v = -1; } + tx2 = x2 + kMage * cos(rad) * v; + ty2 = y2 + kMage * sin(rad) * v; + } + tx3 = x3 - kMage; + ty3 = y3; + tx4 = x3 + kMage * 0.5; + ty4 = y3 - kMage * 2; + + cdDrawLine(x1, y1, tx1, ty1, a2, 1); + cdDrawCurve(tx1, ty1, x2, y2, tx2, ty2, 1, 1); + cdDrawLine(tx2, ty2, tx3, ty3, 6, 5); // bolder by force + } + else{ + if(x1 == x2){ + if(y1 < y2){ v = 1; } else { v = -1; } + tx1 = x2; + ty1 = y2 - kMage * v; + } + else if(y1 == y2){ + if(x1 < x2){ v = 1; } else{ v = -1; } + tx1 = x2 - kMage * v; + ty1 = y2; + } + else{ + rad = atan((double)(y2 - y1) / (double)(x2 - x1)); + if(x1 < x2){ v = 1; } else{ v = -1; } + tx1 = x2 - kMage * cos(rad) * v; + ty1 = y2 - kMage * sin(rad) * v; + } + if(x2 == x3){ + if(y2 < y3){ v = 1; } else{ v = -1; } + tx2 = x2; + ty2 = y2 + kMage * v; + } + else if(y2 == y3){ + if(x2 < x3){ v = 1; } else{ v = -1; } + tx2 = x2 + kMage * v; + ty2 = y2; + } + else{ + rad = atan((double)(y3 - y2) / (double)(x3 - x2)); + if(x2 < x3){ v = 1; } else{ v = -1; } + tx2 = x2 + kMage * cos(rad) * v; + ty2 = y2 + kMage * sin(rad) * v; + } + cdDrawLine(x1, y1, tx1, ty1, a2, 1); + cdDrawCurve(tx1, ty1, x2, y2, tx2, ty2, 1, 1); + cdDrawLine(tx2, ty2, x3, y3, 6, a3); // bolder by force + } + break; + case 6: + if(a3 == 5){ + tx1 = x4 - kMage; + ty1 = y4; + tx2 = x4 + kMage * 0.5; + ty2 = y4 - kMage * 2; + if(a2 == 7 || a3 == 7){ + cdDrawCurve(x1, y1, x2, y2, (x2 + x3) / 2, (y2 + y3) / 2, a2, 17); + cdDrawCurve((x2 + x3) / 2, (y2 + y3) / 2, x3, y3, x4, y4, 17, 15); + } + else{ + cdDrawCurve(x1, y1, x2, y2, (x2 + x3) / 2, (y2 + y3) / 2, a2, 8); + cdDrawCurve((x2 + x3) / 2, (y2 + y3) / 2, x3, y3, x4, y4, 1, 15); + } + } + else{ + if(a2 == 7 || a3 == 7){ + cdDrawCurve(x1, y1, x2, y2, (x2 + x3) / 2, (y2 + y3) / 2, a2, 17); + cdDrawCurve((x2 + x3) / 2, (y2 + y3) / 2, x3, y3, x4, y4, 17, a3); + } + else{ + cdDrawCurve(x1, y1, x2, y2, (x2 + x3) / 2, (y2 + y3) / 2, a2, 8); + cdDrawCurve((x2 + x3) / 2, (y2 + y3) / 2, x3, y3, x4, y4, 1, a3); + } + } + break; + case 7: + cdDrawLine(x1, y1, x2, y2, a2, 1); + cdDrawCurve(x2, y2, x3, y3, x4, y4, 1, 7); + break; + case 9: // may not be exist + break; + default: + break; + } + } + + else{ // gothic + switch(a1 % 100){ + case 0: + break; + case 1: + if(a3 == 4){ + if(x1 == x2){ + if(y1 < y2){ v = 1; } else{ v = -1; } + tx1 = x2; + ty1 = y2 - kMage * v; + } + else if(y1 == y2){ + if(x1 < x2){ v = 1; } else{ v = -1; } + tx1 = x2 - kMage * v; + ty1 = y2; + } + else{ + rad = atan((double)(y2 - y1) / (double)(x2 - x1)); + if(x1 < x2){ v = 1; } else{ v = -1; } + tx1 = x2 - kMage * cos(rad) * v; + ty1 = y2 - kMage * sin(rad) * v; + } + cdDrawLine(x1, y1, tx1, ty1, a2, 1); + cdDrawCurve(tx1, ty1, x2, y2, x2 - kMage * 2, y2 - kMage * 0.5, 1, 0); + } + else{ + cdDrawLine(x1, y1, x2, y2, a2, a3); + } + break; + case 2: + case 12: + if(a3 == 4){ + if(x2 == x3){ + tx1 = x3; + ty1 = y3 - kMage; + } + else if(y2 == y3){ + tx1 = x3 - kMage; + ty1 = y3; + } + else{ + rad = atan((double)(y3 - y2) / (double)(x3 - x2)); + if(x2 < x3){ v = 1; } else{ v = -1; } + tx1 = x3 - kMage * cos(rad) * v; + ty1 = y3 - kMage * sin(rad) * v; + } + cdDrawCurve(x1, y1, x2, y2, tx1, ty1, a2, 1); + cdDrawCurve(tx1, ty1, x3, y3, x3 - kMage * 2, y3 - kMage * 0.5, 1, 0); + } + else if(a3 == 5){ + tx1 = x3 + kMage; + ty1 = y3; + tx2 = tx1 + kMage * 0.5; + ty2 = y3 - kMage * 2; + cdDrawCurve(x1, y1, x2, y2, x3, y3, a2, 1); + cdDrawCurve(x3, y3, tx1, ty1, tx2, ty2, 1, 0); + } + else{ + cdDrawCurve(x1, y1, x2, y2, x3, y3, a2, a3); + } + break; + case 3: + if(a3 == 5){ + if(x1 == x2){ + if(y1 < y2){ v = 1; } else{ v = -1; } + tx1 = x2; + ty1 = y2 - kMage * v; + } + else if(y1 == y2){ + if(x1 < x2){ v = 1; } else{ v = -1; } + tx1 = x2 - kMage * v; + ty1 = y2; + } + else{ + rad = atan((double)(y2 - y1) / (double)(x2 - x1)); + if(x1 < x2){ v = 1; } else{ v = -1; } + tx1 = x2 - kMage * cos(rad) * v; + ty1 = y2 - kMage * sin(rad) * v; + } + if(x2 == x3){ + if(y2 < y3){ v = 1; } else{ v = -1; } + tx2 = x2; + ty2 = y2 + kMage * v; + } + else if(y2 == y3){ + if(x2 < x3){ v = 1; } else{ v = -1; } + tx2 = x2 + kMage * v; + ty2 = y2; + } + else{ + rad = atan((double)(y3 - y2) / (double)(x3 - x2)); + if(x2 < x3){ v = 1; } else{ v = -1; } + tx2 = x2 + kMage * cos(rad) * v; + ty2 = y2 + kMage * sin(rad) * v; + } + tx3 = x3 - kMage; + ty3 = y3; + tx4 = x3 + kMage * 0.5; + ty4 = y3 - kMage * 2; + + cdDrawLine(x1, y1, tx1, ty1, a2, 1); + cdDrawCurve(tx1, ty1, x2, y2, tx2, ty2, 1, 1); + cdDrawLine(tx2, ty2, tx3, ty3, 1, 1); + cdDrawCurve(tx3, ty3, x3, y3, tx4, ty4, 1, 0); + } + else{ + if(x1 == x2){ + if(y1 < y2){ v = 1; } else{ v = -1; } + tx1 = x2; + ty1 = y2 - kMage * v; + } + else if(y1 == y2){ + if(x1 < x2){ v = 1; } else{ v = -1; } + tx1 = x2 - kMage * v; + ty1 = y2; + } + else{ + rad = atan((double)(y2 - y1) / (double)(x2 - x1)); + if(x1 < x2){ v = 1; } else{ v = -1; } + tx1 = x2 - kMage * cos(rad) * v; + ty1 = y2 - kMage * sin(rad) * v; + } + if(x2 == x3){ + if(y2 < y3){ v = 1; } else{ v = -1; } + tx2 = x2; + ty2 = y2 + kMage * v; + } + else if(y2 == y3){ + if(x2 < x3){ v = 1; } else{ v = -1; } + tx2 = x2 + kMage * v; + ty2 = y2; + } + else{ + rad = atan((double)(y3 - y2) / (double)(x3 - x2)); + if(x2 < x3){ v = 1; } else{ v = -1; } + tx2 = x2 + kMage * cos(rad) * v; + ty2 = y2 + kMage * sin(rad) * v; + } + + cdDrawLine(x1, y1, tx1, ty1, a2, 1); + cdDrawCurve(tx1, ty1, x2, y2, tx2, ty2, 1, 1); + cdDrawLine(tx2, ty2, x3, y3, 1, a3); + } + break; + case 6: + if(a3 == 5){ + tx1 = x4 - kMage; + ty1 = y4; + tx2 = x4 + kMage * 0.5; + ty2 = y4 - kMage * 2; + cdDrawCurve(x1, y1, x2, y2, (x2 + x3) / 2, (y2 + y3) / 2, a2, 1); + cdDrawCurve((x2 + x3) / 2, (y2 + y3) / 2, x3, y3, tx1, ty1, 1, 1); + cdDrawCurve(tx1, ty1, x4, y4, tx2, ty2, 1, 0); + } + else{ + cdDrawCurve(x1, y1, x2, y2, (x2 + x3) / 2, (y2 + y3) / 2, a2, 1); + cdDrawCurve((x2 + x3) / 2, (y2 + y3) / 2, x3, y3, x4, y4, 1, a3); + } + break; + case 7: + cdDrawLine(x1, y1, x2, y2, a2, 1); + cdDrawCurve(x2, y2, x3, y3, x4, y4, 1, a3); + break; + case 9: // may not be exist + break; + default: + break; + } + } +} diff --git a/kagecgi/kageeg.c b/kagecgi/kageeg.c new file mode 100755 index 0000000..7fb3613 --- /dev/null +++ b/kagecgi/kageeg.c @@ -0,0 +1,306 @@ +//kageeg.c +// + +#include +//#include + +#include +#include +#include "kagecgi.h" +#include "kage.h" + +void generateGlyphByIDS(const GString *in, GString *out, int flag){ + GString *tmp1, *tmp2, *tmp3, *tmp4; + + //pass this method if 'in' is not UCS parts + if((in->str)[0] != 'u'){ + generateGlyph(in, out); + return; + } + //pass this method if 'in' is place-variant-flag defined + if(in->len < 5 && 7 < in->len){ + generateGlyph(in, out); + return; + } + + tmp1 = g_string_new(in->str); + tmp2 = g_string_new(in->str); +// tmp3 = g_string_new(in->str); +// tmp4 = g_string_new(in->str); + + //append design flag +// if(kDesign == 10) g_string_append(tmp1, "-10"); +// else if(kDesign == 11) g_string_append(tmp1, "-11"); +// else if(kDesign == 20) g_string_append(tmp1, "-20"); +// else if(kDesign == 30) g_string_append(tmp1, "-30"); +// else if(kDesign == 40) g_string_append(tmp1, "-40"); +// else g_string_append(tmp1, "-00"); +// if(kDesign == 10) g_string_append(tmp2, "-10"); +// else if(kDesign == 11) g_string_append(tmp2, "-11"); +// else if(kDesign == 20) g_string_append(tmp2, "-20"); +// else if(kDesign == 30) g_string_append(tmp2, "-30"); +// else if(kDesign == 40) g_string_append(tmp2, "-40"); +// else g_string_append(tmp2, "-00"); +// g_string_append(tmp3, "-00"); +// g_string_append(tmp4, "-00"); + + //append place flag + if(1 <= flag && flag <= 7){ + if(tmp1->len != 7) g_string_append(tmp1, "-"); + if(flag == 1) g_string_append(tmp1, "01"); + else if(flag == 2) g_string_append(tmp1, "02"); + else if(flag == 3) g_string_append(tmp1, "03"); + else if(flag == 4) g_string_append(tmp1, "04"); + else if(flag == 5) g_string_append(tmp1, "05"); + else if(flag == 6) g_string_append(tmp1, "06"); + } + +// g_string_append(tmp2, "00"); +// if(flag == 1) g_string_append(tmp3, "01"); +// else if(flag == 2) g_string_append(tmp3, "02"); +// else if(flag == 3) g_string_append(tmp3, "03"); +// else if(flag == 4) g_string_append(tmp3, "04"); +// else if(flag == 5) g_string_append(tmp3, "05"); +// else if(flag == 6) g_string_append(tmp3, "06"); +// else g_string_append(tmp3, "00"); +// g_string_append(tmp4, "00"); + + generateGlyph(tmp1, out); + if(out->len != 0) return; + generateGlyph(tmp2, out); + if(out->len != 0) return; +// generateGlyph(tmp3, out); +// if(out->len != 0) return; +// generateGlyph(tmp4, out); + return; +} + +void generateGlyph(const GString *in, GString *out){ + GString *tmp, *in2; + tmp = g_string_new(""); + g_string_set_size(out, 0); + +// in2 = g_string_new(in->str); + + //1st search +// if(*(in2->str) == 'u' && (in2->len == 4 || in2->len == 5)){ +// //append design flag +// if(kDesign == 10) g_string_append(in2, "-1000"); +// else if(kDesign == 11) g_string_append(in2, "-1100"); +// else if(kDesign == 20) g_string_append(in2, "-2000"); +// else if(kDesign == 30) g_string_append(in2, "-3000"); +// else if(kDesign == 40) g_string_append(in2, "-4000"); +// else g_string_append(in2, "-0000"); + + //search from parts(1st) +// searchPartsData(in2, tmp); +// if(tmp->len != 0){ +// g_string_assign(out, tmp->str); +// return; +// } + + //search from alias(1st) +// searchAliasData(in2, tmp); +// if(tmp->len != 0){ +// generateGlyph(tmp, out); +// if(out->len == 0) return; +// //save to cache ... not yet +// return; +// } +// } + + //2nd search + //search from parts(2nd) + searchPartsData(in, tmp); + if(tmp->len != 0){ + g_string_assign(out, tmp->str); + return; + } + + //search from alias(2nd) + searchAliasData(in, tmp); + if(tmp->len != 0){ + generateGlyph(tmp, out); + if(out->len == 0) return; + //save to cache ... not yet + return; + } + + //check if its IDS + if(isIDS(in)){ + doCombine(in, out); + if(out->len == 0) return; + //save to cache ... not yet + return; + } +} + +void doCombine(const GString *in, GString *out){ + GString *partIDS1, *partIDS2, *partIDS3; + GString *partStroke1, *partStroke2, *partStroke3; + int result[12]; + + partIDS1 = g_string_new(""); + partIDS2 = g_string_new(""); + partIDS3 = g_string_new(""); + partStroke1 = g_string_new(""); + partStroke2 = g_string_new(""); + partStroke3 = g_string_new(""); + + g_string_set_size(out, 0); + + //check first IDC + if(strncmp(in->str, "u2ff", 4) != 0) return; + //switch by combine types + switch((in->str)[4]){ + case '0': + divideInto2(in, partIDS1, partIDS3); + if(partIDS1->len == 0) return; + //ready each parts + generateGlyphByIDS(partIDS1, partStroke1, 1); + if(partStroke1->len == 0) return; + partStroke1 = CalcSizes(partStroke1, 0); + generateGlyphByIDS(partIDS3, partStroke3, 2); + if(partStroke3->len == 0) return; + partStroke3 = CalcSizes(partStroke3, 0); + break; + case '1': + divideInto2(in, partIDS1, partIDS3); + if(partIDS1->len == 0) return; + //ready each parts + generateGlyphByIDS(partIDS1, partStroke1, 3); + if(partStroke1->len == 0) return; + partStroke1 = CalcSizes(partStroke1, 0); + generateGlyphByIDS(partIDS3, partStroke3, 4); + if(partStroke3->len == 0) return; + partStroke3 = CalcSizes(partStroke3, 0); + break; + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case 'a': +// case 'b': + divideInto2(in, partIDS1, partIDS3); + if(partIDS1->len == 0) return; + //ready each parts + generateGlyphByIDS(partIDS1, partStroke1, 5); + if(partStroke1->len == 0) return; + partStroke1 = CalcSizes(partStroke1, 0); + generateGlyphByIDS(partIDS3, partStroke3, 6); + if(partStroke3->len == 0) return; + partStroke3 = CalcSizes(partStroke3, 0); + break; + case '2': + divideInto3(in, partIDS1, partIDS2, partIDS3); + if(partIDS1->len == 0) return; + //ready each parts + generateGlyphByIDS(partIDS1, partStroke1, 1); + if(partStroke1->len == 0) return; + partStroke1 = CalcSizes(partStroke1, 0); + generateGlyphByIDS(partIDS2, partStroke2, 1); + if(partStroke2->len == 0) return; + partStroke2 = CalcSizes(partStroke2, 0); + generateGlyphByIDS(partIDS3, partStroke3, 2); + if(partStroke3->len == 0) return; + partStroke3 = CalcSizes(partStroke3, 0); + break; + case '3': + divideInto3(in, partIDS1, partIDS2, partIDS3); + if(partIDS1->len == 0) return; + //ready each parts + generateGlyphByIDS(partIDS1, partStroke1, 3); + if(partStroke1->len == 0) return; + partStroke1 = CalcSizes(partStroke1, 0); + generateGlyphByIDS(partIDS2, partStroke2, 3); + if(partStroke2->len == 0) return; + partStroke2 = CalcSizes(partStroke2, 0); + generateGlyphByIDS(partIDS3, partStroke3, 4); + if(partStroke3->len == 0) return; + partStroke3 = CalcSizes(partStroke3, 0); + break; + } + switch((in->str)[4]){ + case '0': + combineYoko2(partStroke1, partStroke3, result); + break; + case '1': + combineTate2(partStroke1, partStroke3, result); + break; + case '2': + combineYoko3(partStroke1, partStroke2, partStroke3, result); + break; + case '3': + combineTate3(partStroke1, partStroke2, partStroke3, result); + break; + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case 'a': +// case 'b': + combineHame2(partStroke1, partStroke3, result); + break; + } + switch((in->str)[4]){ + case '0': + case '1': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case 'a': +// case 'b': + addStrokeWithTransform(partStroke1, 1, result, out, 1); + addStrokeWithTransform(partStroke3, 3, result, out, 1); + break; + case '2': + case '3': + addStrokeWithTransform(partStroke1, 1, result, out, 1); + addStrokeWithTransform(partStroke2, 2, result, out, 1); + addStrokeWithTransform(partStroke3, 3, result, out, 1); + break; + } +} + +void drawGlyph(const GString *in, const int mode){ + int i, j; + int *buf; + buf = convertStroke(in->str, buf, &j); + for(i = 0; i < j; i++){ + if(mode == 0){ //normal + dfDrawFont(buf[i * 11 + 0], + buf[i * 11 + 1], + buf[i * 11 + 2], + buf[i * 11 + 3], + buf[i * 11 + 4], + buf[i * 11 + 5], + buf[i * 11 + 6], + buf[i * 11 + 7], + buf[i * 11 + 8], + buf[i * 11 + 9], + buf[i * 11 + 10]); + } + else if(mode == 1){ //without decoration + dfDrawFont(buf[i * 11 + 0], + 0, + 0, + buf[i * 11 + 3], + buf[i * 11 + 4], + buf[i * 11 + 5], + buf[i * 11 + 6], + buf[i * 11 + 7], + buf[i * 11 + 8], + buf[i * 11 + 9], + buf[i * 11 + 10]); + } + } + free(buf); +} + diff --git a/kagecgi/kageic.c b/kagecgi/kageic.c new file mode 100755 index 0000000..70281dc --- /dev/null +++ b/kagecgi/kageic.c @@ -0,0 +1,25 @@ +//kageic.c +// + +#include "kage.h" +#include "kagecgi.h" + +void icPolygon(struct kPoint *poly, int number){ + int i; + char buf[256]; + + if(kMode == 0){ //normal + fillPolygon(poly, number, 0, kageCanvas); + } + else{ //output for eps + sprintf(buf, "%d %d moveto\n", poly[0].X * 5, 1000 - (poly[0].Y * 5) - 200); + g_string_append(kResultText, buf); + for(i = 1; i < number; i++){ + sprintf(buf, " %d %d lineto\n", poly[i].X * 5, 1000 - (poly[i].Y * 5) - 200); + g_string_append(kResultText, buf); + } + sprintf(buf, " %d %d lineto\n", poly[0].X * 5, 1000 - (poly[0].Y * 5) - 200); + g_string_append(kResultText, buf); + g_string_append(kResultText, "closepath\n"); + } +} diff --git a/kagecgi/kagepng.c b/kagecgi/kagepng.c new file mode 100755 index 0000000..7080bb7 --- /dev/null +++ b/kagecgi/kagepng.c @@ -0,0 +1,84 @@ +//kagepng.c +// + +#include +#include +#include + +png_bytepp initPng(int width, int height){ + png_bytepp image; + int i, j; + + image = (png_bytepp)malloc(height * sizeof(png_bytep)); + for(j = 0; j < height; j++) image[j] = (png_bytep)malloc(width * sizeof(png_byte)); + for(i = 0; i < width; i++){ + for(j = 0; j < height; j++){ + image[j][i] = 0xFF; + } + } + return image; +} + +int closePng(int width, int height, png_bytepp image){ + int i; + for(i = 0; i < height; i++) free(image[i]); + free(image); + return 0; +} + +int writePng(int width, int height, png_bytepp image, FILE *fp){ + png_structp pPng; + png_infop pInfo; + png_text pText[5]; + time_t gmt; + png_time pngTime; + + pPng = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if(pPng == NULL){ + return 1; + } + pInfo = png_create_info_struct(pPng); + if(pInfo == NULL){ + png_destroy_write_struct(&pPng, (png_infopp)NULL); + return 1; + } + if(setjmp(pPng->jmpbuf)){ + png_destroy_write_struct(&pPng, &pInfo); + return 1; + } + png_init_io(pPng, fp); + png_set_filter(pPng, 0, PNG_ALL_FILTERS); + png_set_compression_level(pPng, Z_BEST_COMPRESSION); + //png_set_IHDR(pPng, pInfo, width, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + png_set_IHDR(pPng, pInfo, width, height, 8, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + png_set_gAMA(pPng, pInfo, 1.0); + + time(&gmt); + png_convert_from_time_t(&pngTime, gmt); + png_set_tIME(pPng, pInfo, &pngTime); + + pText[0].key = "Title"; + pText[0].text = "Kanji glyph generated by KAGE/cgi"; + pText[0].compression = PNG_TEXT_COMPRESSION_NONE; + pText[1].key = "Author"; + pText[1].text = "KAGE/cgi version 0.4"; + pText[1].compression = PNG_TEXT_COMPRESSION_NONE; + pText[2].key = "Description"; + pText[2].text = "see more information at http://fonts.jp/"; + pText[2].compression = PNG_TEXT_COMPRESSION_NONE; + pText[3].key = "Creation Time"; + pText[3].text = png_convert_to_rfc1123(pPng, &pngTime); + pText[3].compression = PNG_TEXT_COMPRESSION_NONE; + pText[4].key = "Software"; + pText[4].text = "KAGE/cgi version 0.4"; + pText[4].compression = PNG_TEXT_COMPRESSION_NONE; + png_set_text(pPng, pInfo, pText, 5); + + png_write_info(pPng, pInfo); + png_write_image(pPng, image); + png_write_end(pPng, pInfo); + png_destroy_write_struct(&pPng, &pInfo); + + return 0; +} + diff --git a/kagecgi/kagepoly.c b/kagecgi/kagepoly.c new file mode 100755 index 0000000..358148e --- /dev/null +++ b/kagecgi/kagepoly.c @@ -0,0 +1,29 @@ +// kagepoly.c +// + +#include +#include +#include "kagecgi.h" +#include "kage.h" + +void fillPolygon(struct kPoint *p, int number, int col, unsigned char **image){ + int i, ix, iy; + Region rgn; + XRectangle rect; + + for(i = 0; i < number; i++){ + xpoly[i].x = p[i].X; + xpoly[i].y = p[i].Y; + } + rgn = XPolygonRegion(xpoly, number, EvenOddRule); + XClipBox(rgn, &rect); + + for(ix = rect.x ; ix <= rect.x + rect.width; ix++){ + for(iy = rect.y ; iy <= rect.y + rect.height; iy++){ + if(XPointInRegion(rgn, ix, iy) && ix >= 0 && iy >= 0 && ix < canvasWidth && iy < canvasHeight){ + image[iy][ix] = col; + } + } + } +} + diff --git a/kagecgi/kagetool.c b/kagecgi/kagetool.c new file mode 100755 index 0000000..5c5a96e --- /dev/null +++ b/kagecgi/kagetool.c @@ -0,0 +1,466 @@ +//kagetool.c +// + +#include "kage.h" +#include "kagecgi.h" +#include +#include + +void DotsWidth(int *dlx, int *drx){ + int i, j; + + *dlx = 0; + *drx = 0; + for(i = 0; i <= pngWidth && *dlx == 0; i++){ + for(j = 0; j <= pngHeight; j++){ + if(kageCanvas[j][i] == 0){ + *dlx = i; + break; + } + } + } + + for(i = pngWidth; i >= 0 && *drx == 0; i--){ + for(j = 0; j <= pngHeight; j++){ + if(kageCanvas[j][i] == 0){ + *drx = i; + break; + } + } + } +} + +void DotsHeight(int *dly, int *dry){ + int i, j; + + *dly = 0; + *dry = 0; + for(j = 0; j <= pngHeight && *dly == 0; j++){ + for(i = 0; i <= pngWidth; i++){ + if(kageCanvas[j][i] == 0){ + *dly = j; + break; + } + } + } + + for(j = pngHeight; j >= 0 && *dry == 0; j--){ + for(i = 0; i <= pngWidth; i++){ + if(kageCanvas[j][i] == 0){ + *dry = j; + break; + } + } + } +} + +void PartsWidth(const GString *in, int *lx, int *rx){ + int i; + int *buf, strokes; + + *lx = 1000; *rx = 0; + buf = convertStroke(in->str, buf, &strokes); + + for(i = 0; i < strokes; i++){ + if(buf[i * 11 + 0] % 10 == 0) continue; + + if(*lx > buf[i * 11 + 3]) *lx = buf[i * 11 + 3]; + if(*rx < buf[i * 11 + 3]) *rx = buf[i * 11 + 3]; + if(*lx > buf[i * 11 + 5]) *lx = buf[i * 11 + 5]; + if(*rx < buf[i * 11 + 5]) *rx = buf[i * 11 + 5]; + + if(buf[i * 11 + 0] % 10 == 2 || buf[i * 11 + 0] % 10 == 3 || buf[i * 11 + 0] % 10 == 8){ + if(*lx > buf[i * 11 + 7]) *lx = buf[i * 11 + 7]; + if(*rx < buf[i * 11 + 7]) *rx = buf[i * 11 + 7]; + } + if(buf[i * 11 + 0] % 10 == 4 || buf[i * 11 + 0] % 10 == 6 || buf[i * 11 + 0] % 10 == 7){ + if(*lx > buf[i * 11 + 9]) *lx = buf[i * 11 + 9]; + if(*rx < buf[i * 11 + 9]) *rx = buf[i * 11 + 9]; + } + } + free(buf); +} + +void PartsHeight(const GString *in, int *ly, int *ry){ + int i; + int *buf, strokes; + + buf = convertStroke(in->str, buf, &strokes); + *ly = 1000; *ry = 0; + + for(i = 0; i < strokes; i++){ + if(buf[i * 11 + 0] % 10 == 0) continue; + + if(*ly > buf[i * 11 + 4]) *ly = buf[i * 11 + 4]; + if(*ry < buf[i * 11 + 4]) *ry = buf[i * 11 + 4]; + if(*ly > buf[i * 11 + 6]) *ly = buf[i * 11 + 6]; + if(*ry < buf[i * 11 + 6]) *ry = buf[i * 11 + 6]; + + if(buf[i * 11 + 0] % 10 == 2 || buf[i * 11 + 0] % 10 == 3 || buf[i * 11 + 0] % 10 == 8){ + if(*ly > buf[i * 11 + 8]) *ly = buf[i * 11 + 8]; + if(*ry < buf[i * 11 + 8]) *ry = buf[i * 11 + 8]; + } + if(buf[i * 11 + 0] % 10 == 4 || buf[i * 11 + 0] % 10 == 6 || buf[i * 11 + 0] % 10 == 7){ + if(*ly > buf[i * 11 + 10]) *ly = buf[i * 11 + 10]; + if(*ry < buf[i * 11 + 10]) *ry = buf[i * 11 + 10]; + } + } + free(buf); +} + +GString * CalcSizes(const GString *in, int mode){ + int i, j, k, basewidth, one_lineX, one_lineY; + int dlx1, drx1, dly1, dry1; + int px1, py1; + double pr1, pry1; + + int mitsuT, flg_boxT, widthT, heightT; + double tateT, yokoT; + int cutx, cuty; + + int *buf, strokes; + int tf[12]; + GString *out; + + out = g_string_new(""); + basewidth = pngWidth * 0.9; + + if(mode == 0){ + //temporary adjustment X-axis + PartsWidth(in, &dlx1, &drx1); + if(dlx1 == drx1){ + pr1 = 1.0; + px1 = pngWidth / 2 - dlx1; + one_lineX = 1; + } + else{ + pr1 = (double)basewidth/(drx1 - dlx1); + px1 = (pngWidth-basewidth)/2 - (double)(dlx1 * pr1); + one_lineX = 0; + } + + //temporary adjustment Y-axis + PartsHeight(in, &dly1, &dry1); + if(dly1 == dry1){ + pry1 = 1.0; + py1 = pngWidth / 2 - dly1; + one_lineY = 1; + } + else{ + pry1 = (double)basewidth/(dry1 - dly1); + py1 = (pngWidth-basewidth)/2 - (double)(dly1 * pry1); + one_lineY = 0; + } + } + else{ + PartsWidth(in, &dlx1, &drx1); + PartsHeight(in, &dly1, &dry1); + + cutx = 0; + cuty = 0; + + CalcOptions(in, &mitsuT, &flg_boxT, &yokoT, &tateT); + + widthT = basewidth; + heightT = basewidth; + + if(flg_boxT % 2 / 1 != 0){ + widthT = widthT - kWidth * 3; + cutx++; + } + if(flg_boxT % 4 / 2 != 0){ + widthT = widthT - kWidth * 3; + cutx++; + } + if(flg_boxT % 8 / 4 != 0){ + heightT = heightT - kWidth * 3; + cuty++; + } + if(flg_boxT % 16 / 8 != 0){ + heightT = heightT - kWidth * 3; + cuty++; + } + + //especially get small the 'mouse' + if(mode == 2 && flg_boxT % 16 == 15){ + widthT = widthT - kWidth * (max(0, 16 - (int)yokoT * 4)); + heightT = heightT - kWidth * (max(0, 16 - (int)tateT * 4)); + } + //'dot' as same as 'mouse' + if(mode == 2 && tateT == 1 && yokoT == 1){ + widthT = pngWidth * 0.9 * 0.5; + heightT = pngWidth * 0.9 * 0.5; + } + + if(flg_boxT % 64 / 32 != 0){ + buf = convertStroke(in->str, buf, &strokes); + for(i = 0; i < strokes; i++){ + if(buf[i * 11 + 0] == 0) j = buf[i * 11 + 4];// j : center line + } + free(buf); + k = max(j - dlx1, drx1 - j);// k : distance from center line + pr1 = (basewidth * 0.5) / k; + + if(k == j - dlx1) px1 = 0; + else px1 = pngWidth * 0.5 - j * pr1; + } + else if(dlx1 == drx1){ + pr1 = 1.0; + px1 = pngWidth / 2 - dlx1; + } + else{ + pr1 = (double)widthT/(drx1 - dlx1); + px1 = pngWidth / 2 - (double)((dlx1 + drx1) / 2 * pr1); + if(flg_boxT % 2 / 1 != 0 && flg_boxT % 4 / 2 == 0) px1 = px1 + kWidth * 1.5; + if(flg_boxT % 2 / 1 == 0 && flg_boxT % 4 / 2 != 0) px1 = px1 - kWidth * 1.5; + } + + if(dly1 == dry1){ + pry1 = 1.0; + py1 = pngWidth / 2 - dly1; + } + else{ + pry1 = (double)heightT/(dry1 - dly1); + py1 = pngWidth / 2 - (double)((dly1 + dry1) / 2 * pry1); + if(flg_boxT % 8 / 4 != 0 && flg_boxT % 16 / 8 == 0) py1 = py1 + kWidth * 1.5; + if(flg_boxT % 8 / 4 == 0 && flg_boxT % 16 / 8 != 0) py1 = py1 - kWidth * 1.5; + } + } + + //generate result + tf[0] = px1; + tf[1] = py1; + tf[2] = px1 + pr1 * 200; + tf[3] = py1 + pry1 * 200; + addStrokeWithTransform(in, 1, tf, out, 0); + return g_string_new(out->str); +} + +void DrawBox(){ + int i, j; + + for(i = 0; i < canvasWidth; i++){ + for(j = 0; j < canvasHeight; j++){ + kageCanvas[j][i] = 0xFF; + } + } +} + +void CalcOptions(const GString *in, int *mitsudo, int *flag, double *yoko, double *tate){ + int i, j, k, l, flg; + int dlx1, drx1, dly1, dry1; + int kari, mode; + int tempShotai; + int *buf, strokes; + + *flag = 0; + + DrawBox(); + tempShotai = kShotai; + kShotai = kGothic; + drawGlyph(in, 1); + kShotai = tempShotai; + DotsWidth(&dlx1, &drx1); + DotsHeight(&dly1, &dry1); + + //check left side + k = 0; + l = 0; + for(i = 0; i < pngWidth; i++){ + flg = 0; + for(j = 0; j < kWidth; j++){ + if(kageCanvas[i][dlx1 + j] == 0) flg = 1; + } + if(flg == 1){ + k++; + } + else{ + if(k > l) l = k; + k = 0; + } + } + if(k > l) l = k; + + if(l > pngWidth * 0.9 / 4) *flag = *flag | 1; + + //check right side + k = 0; + l = 0; + for(i = 0; i < pngWidth; i++){ + flg = 0; + for(j = 0; j < kWidth; j++){ + if(kageCanvas[i][drx1 - j] == 0) flg = 1; + } + if(flg == 1) k++; + else{ + if(k > l) l = k; + k = 0; + } + } + if(k > l) l = k; + + if(l > pngWidth * 0.9 / 4) *flag = *flag | 2; + + //check upper side + k = 0; + l = 0; + for(i = 0; i < pngWidth; i++){ + flg = 0; + for(j = 0; j < kWidth; j++){ + if(kageCanvas[dly1 + j][i] == 0) flg = 1; + } + if(flg == 1) k++; + else{ + if(k > l) l = k; + k = 0; + } + } + if(k > l) l = k; + + if(l > pngWidth * 0.9 / 4) *flag = *flag | 4; + + //check bottom side + k = 0; + l = 0; + for(i = 0; i < pngWidth; i++){ + flg = 0; + for(j = 0; j < kWidth; j++){ + if(kageCanvas[dry1 - j][i] == 0) flg = 1; + } + if(flg == 1) k++; + else{ + if(k > l) l = k; + k = 0; + } + } + if(k > l) l = k; + + if(l > pngWidth * 0.9 / 4) *flag = *flag | 8; + + //count black dots + *mitsudo = 0; + for(i = 0; i < pngHeight; i++){ + for(j = 0; j < pngWidth; j++){ + if(kageCanvas[i][j] == 0) *mitsudo += 1; + } + } + + //calculate X-axis complexity + *yoko = 0; + for(i = dly1; i <= dry1; i++){ + mode = 0; + kari = 0; + for(j = dlx1; j <= drx1; j++){ + if(kageCanvas[i][j] == 0 && + kageCanvas[i][j+1] == 0 && + kageCanvas[i][j+2] == 0){ + if(mode == 0){ + mode = 1; + kari++; + } + } + else if(mode == 1) mode = 0; + } + if(kari > *yoko) *yoko = kari; + } + + //calculate Y-axis complexity + *tate = 0; + for(i = dlx1; i <= drx1; i++){ + mode = 0; + kari = 0; + for(j = dly1; j <= dry1; j++){ + if(kageCanvas[j][i] == 0 && + kageCanvas[j+1][i] == 0 && + kageCanvas[j+2][i] == 0){ + if(mode == 0){ + mode = 1; + kari++; + } + } + else if(mode == 1) mode = 0; + } + if(kari > *tate) *tate = kari; + } + + //use user defined option if it exists + buf = convertStroke(in->str, buf, &strokes); + for(i = 0; i < strokes; i++){ + if(buf[i * 11 + 0] % 10 == 0){ + if(buf[i * 11 + 1] != 0){ *yoko = (double)(buf[i * 11 + 1]) * 0.1;fprintf(stderr,"@@@@@\r\n");} + if(buf[i * 11 + 2] != 0) *tate = (double)(buf[i * 11 + 2]) * 0.1; + if(buf[i * 11 + 3] != 0) *flag = *flag + buf[i * 11 + 3] * 16; + } + } + free(buf); +} + +void DoDrawParts(const GString *in, const int lx1, const double rf1, const int ly1, const double rfy1){ + int i; + int *buf, strokes; + + DrawBox(); + buf = convertStroke(in->str, buf, &strokes); + for(i = 0; i < strokes; i++){ + dfDrawFont(buf[i * 11 + 0], + buf[i * 11 + 1], + buf[i * 11 + 2], + buf[i * 11 + 3] * rf1 + lx1, + buf[i * 11 + 4] * rfy1 + ly1, + buf[i * 11 + 5] * rf1 + lx1, + buf[i * 11 + 6] * rfy1 + ly1, + buf[i * 11 + 7] * rf1 + lx1, + buf[i * 11 + 8] * rfy1 + ly1, + buf[i * 11 + 9] * rf1 + lx1, + buf[i * 11 + 10] * rfy1 + ly1); + } + free(buf); +} + +void DoDrawMixFont(const GString *in1, + const int lx1, + const double rf1, + const GString *in2, + const int lx2, + const double rf2, + const int ly1, + const double rfy1, + const int ly2, + const double rfy2){ + int i; + int *buf, strokes; + + DrawBox(); + buf = convertStroke(in1->str, buf, &strokes); + for(i = 0; i < strokes; i++){ + dfDrawFont(buf[i * 11 + 0], + buf[i * 11 + 1], + buf[i * 11 + 2], + buf[i * 11 + 3] * rf1 + lx1, + buf[i * 11 + 4] * rfy1 + ly1, + buf[i * 11 + 5] * rf1 + lx1, + buf[i * 11 + 6] * rfy1 + ly1, + buf[i * 11 + 7] * rf1 + lx1, + buf[i * 11 + 8] * rfy1 + ly1, + buf[i * 11 + 9] * rf1 + lx1, + buf[i * 11 + 10] * rfy1 + ly1); + } + free(buf); + + buf = convertStroke(in2->str, buf, &strokes); + for(i = 0; i < strokes; i++){ + dfDrawFont(buf[i * 11 + 0], + buf[i * 11 + 1], + buf[i * 11 + 2], + buf[i * 11 + 3] * rf2 + lx2, + buf[i * 11 + 4] * rfy2 + ly2, + buf[i * 11 + 5] * rf2 + lx2, + buf[i * 11 + 6] * rfy2 + ly2, + buf[i * 11 + 7] * rf2 + lx2, + buf[i * 11 + 8] * rfy2 + ly2, + buf[i * 11 + 9] * rf2 + lx2, + buf[i * 11 + 10] * rfy2 + ly2); + } + free(buf); +} +