From 5d76a98324bc81b76ad8087feb63bea1548cbb4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=F8=EDk?= Date: Tue, 18 Mar 2014 19:56:59 +0100 Subject: [PATCH] Font export (TTF) jar path updated in libsrc projects --- trunk/lib/LZMA.jar | Bin 91326 -> 91320 bytes trunk/lib/avi.jar | Bin 215818 -> 215818 bytes trunk/lib/gif.jar | Bin 6306 -> 6306 bytes trunk/lib/nellymoser.jar | Bin 24836 -> 24836 bytes trunk/lib/ttf.jar | Bin 0 -> 812943 bytes trunk/libsrc/LZMA/build.xml | 3 +- trunk/libsrc/LZMA/nbproject/build-impl.xml | 110 +- .../libsrc/LZMA/nbproject/genfiles.properties | 8 +- .../libsrc/LZMA/nbproject/project.properties | 2 +- trunk/libsrc/avi/nbproject/project.properties | 2 +- trunk/libsrc/gif/nbproject/project.properties | 2 +- .../nellymoser/nbproject/project.properties | 2 +- trunk/libsrc/ttf/build.xml | 73 + trunk/libsrc/ttf/manifest.mf | 3 + trunk/libsrc/ttf/nbproject/build-impl.xml | 1407 +++ .../libsrc/ttf/nbproject/genfiles.properties | 8 + trunk/libsrc/ttf/nbproject/project.properties | 75 + trunk/libsrc/ttf/nbproject/project.xml | 15 + trunk/libsrc/ttf/src/fontastic/FContour.java | 86 + trunk/libsrc/ttf/src/fontastic/FGlyph.java | 116 + trunk/libsrc/ttf/src/fontastic/FPoint.java | 82 + trunk/libsrc/ttf/src/fontastic/Fontastic.java | 518 + trunk/libsrc/ttf/src/fontastic/PVector.java | 27 + trunk/libsrc/ttf/src/fontatest/FontaTest.java | 31 + .../src/org/doubletype/ossa/ActiveList.java | 199 + .../src/org/doubletype/ossa/AppSettings.java | 55 + .../ttf/src/org/doubletype/ossa/Engine.java | 762 ++ .../src/org/doubletype/ossa/GlyphColor.java | 67 + .../org/doubletype/ossa/GlyphFileFilter.java | 60 + .../src/org/doubletype/ossa/HistoryList.java | 104 + .../src/org/doubletype/ossa/ImageSizer.java | 91 + .../ttf/src/org/doubletype/ossa/Memento.java | 89 + .../org/doubletype/ossa/ModuleManager.java | 96 + .../src/org/doubletype/ossa/MyTableModel.java | 73 + .../doubletype/ossa/OutOfRangeException.java | 49 + .../ttf/src/org/doubletype/ossa/Renderer.java | 44 + .../ttf/src/org/doubletype/ossa/Tabbable.java | 5 + .../ossa/TabbedPaneCloseButtonUI.java | 188 + .../doubletype/ossa/TypefaceFileFilter.java | 59 + .../ttf/src/org/doubletype/ossa/UiBridge.java | 12 + .../org/doubletype/ossa/UnicodeBuilder.java | 184 + .../doubletype/ossa/adapter/CubicSegment.java | 398 + .../org/doubletype/ossa/adapter/EContour.java | 243 + .../ossa/adapter/EContourPoint.java | 419 + .../ossa/adapter/EControlPoint.java | 244 + .../ossa/adapter/EGlyphFactory.java | 109 + .../org/doubletype/ossa/adapter/EHint.java | 195 + .../ossa/adapter/EIncludeInvoke.java | 167 + .../ossa/adapter/EModuleInvoke.java | 288 + .../org/doubletype/ossa/adapter/EObject.java | 158 + .../org/doubletype/ossa/adapter/EPoint.java | 44 + .../org/doubletype/ossa/adapter/Emulator.java | 360 + .../doubletype/ossa/adapter/GlyphObject.java | 51 + .../ossa/adapter/PointAggregate.java | 49 + .../ossa/adapter/QuadraticSegment.java | 188 + .../org/doubletype/ossa/module/GlyphFile.java | 1141 +++ .../doubletype/ossa/module/GlyphIterator.java | 237 + .../doubletype/ossa/module/GlyphModule.java | 90 + .../org/doubletype/ossa/module/Rectangle.java | 192 + .../ossa/module/SelectionIterator.java | 69 + .../doubletype/ossa/module/TypefaceFile.java | 677 ++ .../org/doubletype/ossa/module/VarStack.java | 112 + .../doubletype/ossa/module/VarStackFrame.java | 53 + .../org/doubletype/ossa/module/empty.glyph | 21 + .../doubletype/ossa/truetype/CmapWriter.java | 316 + .../ossa/truetype/FontFileWriter.java | 286 + .../ossa/truetype/FontFormatWriter.java | 173 + .../doubletype/ossa/truetype/GlyfWriter.java | 203 + .../doubletype/ossa/truetype/HdmxWriter.java | 117 + .../doubletype/ossa/truetype/HeadWriter.java | 156 + .../doubletype/ossa/truetype/HheaWriter.java | 108 + .../doubletype/ossa/truetype/HmtxWriter.java | 89 + .../doubletype/ossa/truetype/LocaWriter.java | 67 + .../doubletype/ossa/truetype/MaxpWriter.java | 137 + .../doubletype/ossa/truetype/NameWriter.java | 183 + .../doubletype/ossa/truetype/OS2Writer.java | 242 + .../doubletype/ossa/truetype/PostWriter.java | 76 + .../doubletype/ossa/truetype/TTCodePage.java | 189 + .../org/doubletype/ossa/truetype/TTGlyph.java | 391 + .../org/doubletype/ossa/truetype/TTName.java | 93 + .../doubletype/ossa/truetype/TTPixelSize.java | 107 + .../ossa/truetype/TTUnicodeRange.java | 380 + .../ossa/xml/AbstractGlyphFactory.java | 3291 ++++++ .../ossa/xml/DefaultGlyphFactory.java | 394 + .../org/doubletype/ossa/xml/GlyphFactory.java | 55 + .../doubletype/ossa/xml/IGlyphFactory.java | 2279 +++++ .../src/org/doubletype/ossa/xml/IRNode.java | 51 + .../org/doubletype/ossa/xml/RInterleave.java | 757 ++ .../src/org/doubletype/ossa/xml/RStack.java | 287 + .../org/doubletype/ossa/xml/Relaxer.README | 2 + .../org/doubletype/ossa/xml/Relaxer.manifest | 2 + .../doubletype/ossa/xml/Relaxer.properties | 8 + .../src/org/doubletype/ossa/xml/UJAXP.java | 1018 ++ .../src/org/doubletype/ossa/xml/URelaxer.java | 8791 +++++++++++++++++ .../src/org/doubletype/ossa/xml/XBody.java | 1193 +++ .../src/org/doubletype/ossa/xml/XContour.java | 758 ++ .../doubletype/ossa/xml/XContourPoint.java | 1014 ++ .../doubletype/ossa/xml/XControlPoint.java | 665 ++ .../org/doubletype/ossa/xml/XGlyphFile.java | 631 ++ .../src/org/doubletype/ossa/xml/XHead.java | 2545 +++++ .../org/doubletype/ossa/xml/XHeadGlobal.java | 683 ++ .../org/doubletype/ossa/xml/XHeadLocal.java | 683 ++ .../src/org/doubletype/ossa/xml/XHint.java | 607 ++ .../src/org/doubletype/ossa/xml/XInclude.java | 611 ++ .../src/org/doubletype/ossa/xml/XInvoke.java | 929 ++ .../org/doubletype/ossa/xml/XInvokeArg.java | 617 ++ .../org/doubletype/ossa/xml/XInvokePos.java | 547 + .../org/doubletype/ossa/xml/XInvokeVarg.java | 636 ++ .../src/org/doubletype/ossa/xml/XModule.java | 798 ++ .../org/doubletype/ossa/xml/XParamList.java | 451 + .../doubletype/ossa/xml/XParamListParam.java | 617 ++ .../src/org/doubletype/ossa/xml/XPoint2d.java | 626 ++ .../ossa/xml/XStartGlyphElement.java | 586 ++ .../ttf/src/org/doubletype/ossa/xml/glyph.rng | 217 + trunk/nbproject/project.xml | 2 +- trunk/src/com/jpexs/decompiler/flash/SWF.java | 142 + .../console/CommandLineArgumentParser.java | 11 +- .../flash/exporters/PathExporter.java | 2 +- .../flash/exporters/modes/FontExportMode.java | 26 + .../decompiler/flash/gui/ExportDialog.java | 11 +- .../jpexs/decompiler/flash/gui/FontPanel.java | 2 +- .../jpexs/decompiler/flash/gui/MainPanel.java | 15 +- .../flash/gui/locales/ExportDialog.properties | 3 + .../flash/tags/DefineEditTextTag.java | 4 +- .../decompiler/flash/tags/DefineFont2Tag.java | 14 +- .../decompiler/flash/tags/DefineFont3Tag.java | 20 +- .../decompiler/flash/tags/DefineFontTag.java | 24 +- .../decompiler/flash/tags/DefineText2Tag.java | 17 +- .../decompiler/flash/tags/DefineTextTag.java | 17 +- .../decompiler/flash/tags/base/FontTag.java | 41 +- .../tags/base/MissingCharacterHandler.java | 4 +- .../decompiler/flash/tags/base/TextTag.java | 4 +- .../flash/tags/gfx/DefineCompactedFont.java | 14 +- .../decompiler/flash/types/TEXTRECORD.java | 4 +- .../flash/types/shaperecords/SHAPERECORD.java | 2 +- .../decompiler/flash/xfl/XFLConverter.java | 2 +- 136 files changed, 46107 insertions(+), 148 deletions(-) create mode 100644 trunk/lib/ttf.jar create mode 100644 trunk/libsrc/ttf/build.xml create mode 100644 trunk/libsrc/ttf/manifest.mf create mode 100644 trunk/libsrc/ttf/nbproject/build-impl.xml create mode 100644 trunk/libsrc/ttf/nbproject/genfiles.properties create mode 100644 trunk/libsrc/ttf/nbproject/project.properties create mode 100644 trunk/libsrc/ttf/nbproject/project.xml create mode 100644 trunk/libsrc/ttf/src/fontastic/FContour.java create mode 100644 trunk/libsrc/ttf/src/fontastic/FGlyph.java create mode 100644 trunk/libsrc/ttf/src/fontastic/FPoint.java create mode 100644 trunk/libsrc/ttf/src/fontastic/Fontastic.java create mode 100644 trunk/libsrc/ttf/src/fontastic/PVector.java create mode 100644 trunk/libsrc/ttf/src/fontatest/FontaTest.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/ActiveList.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/AppSettings.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/Engine.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/GlyphColor.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/GlyphFileFilter.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/HistoryList.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/ImageSizer.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/Memento.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/ModuleManager.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/MyTableModel.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/OutOfRangeException.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/Renderer.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/Tabbable.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/TabbedPaneCloseButtonUI.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/TypefaceFileFilter.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/UiBridge.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/UnicodeBuilder.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/CubicSegment.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EContour.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EContourPoint.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EControlPoint.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EGlyphFactory.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EHint.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EIncludeInvoke.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EModuleInvoke.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EObject.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EPoint.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/Emulator.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/GlyphObject.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/PointAggregate.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/QuadraticSegment.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/module/GlyphFile.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/module/GlyphIterator.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/module/GlyphModule.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/module/Rectangle.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/module/SelectionIterator.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/module/TypefaceFile.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/module/VarStack.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/module/VarStackFrame.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/module/empty.glyph create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/CmapWriter.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/FontFileWriter.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/FontFormatWriter.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/GlyfWriter.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/HdmxWriter.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/HeadWriter.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/HheaWriter.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/HmtxWriter.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/LocaWriter.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/MaxpWriter.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/NameWriter.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/OS2Writer.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/PostWriter.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/TTCodePage.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/TTGlyph.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/TTName.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/TTPixelSize.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/TTUnicodeRange.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/xml/AbstractGlyphFactory.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/xml/DefaultGlyphFactory.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/xml/GlyphFactory.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/xml/IGlyphFactory.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/xml/IRNode.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/xml/RInterleave.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/xml/RStack.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/xml/Relaxer.README create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/xml/Relaxer.manifest create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/xml/Relaxer.properties create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/xml/UJAXP.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/xml/URelaxer.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/xml/XBody.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/xml/XContour.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/xml/XContourPoint.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/xml/XControlPoint.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/xml/XGlyphFile.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/xml/XHead.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/xml/XHeadGlobal.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/xml/XHeadLocal.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/xml/XHint.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/xml/XInclude.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/xml/XInvoke.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/xml/XInvokeArg.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/xml/XInvokePos.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/xml/XInvokeVarg.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/xml/XModule.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/xml/XParamList.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/xml/XParamListParam.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/xml/XPoint2d.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/xml/XStartGlyphElement.java create mode 100644 trunk/libsrc/ttf/src/org/doubletype/ossa/xml/glyph.rng create mode 100644 trunk/src/com/jpexs/decompiler/flash/exporters/modes/FontExportMode.java diff --git a/trunk/lib/LZMA.jar b/trunk/lib/LZMA.jar index aa485ec25a2a4a9c8561682427858ea303600946..dc74d72bee579e6b5f0fcabe3e01b1d46ccae42d 100644 GIT binary patch delta 2950 zcmZWrdr(x@8UKCv?t@+S0Sb!{ke5g>f&$`$Odv)~!5C`lV?yVZ~G^=QO%Z#$Zw&K}Y_ty4?+E;dF&Fk*%>Fy2ncXh8G`l!(&qG_3w zYk-GongKRYi2>fC83wpcs*ElZeU_V*V%YAK z_c#pHTlKWb-u53gqa3M!!n92cR9nm_!Lr3}vB|7syU*;J0PND<3YQJM?nEx0av%qT zVtQIk+r{*Zn0_IqU#cJr1ll2-cM9|?G3|2lv|HHrh{wHZ<>=_Bu!tO!04#TK*oE{QOL}Gu|!6AUO4Jv`n3}W@EbwApx!t!m}SR{cKkNH@12{J{vyG$ zV0BkNfw~CJ`Rm&|d&DX9*)bd*J~m%ztj2>bOhJJQlaS}aLHxvpT48%hJZ==I4!?6D zUp(F`{H6+YNKC&MQ-!b{#>;lR;=-$V&4qrfC1h%$D-*PXJ@#xQ-B`L}e#FM;oJYiiS&QXEdG< zaSf_4pHmCefdWpMqt?R6R-#s-ll@dI98mM{I717TsA*Wn$cliPg5`{C_@}bN*bJ7c zN$6r*99q>xJi*9;@03kg!N^G$=^$1zil@&=$0|lH`jYlwH6u5DLHp3n$fJ}}1$r2H zr7C;jo1k6!Q{o)I9cxH@z<(G;2Aq6m5u>o<4mR@t$?4xCVU!QrYw%j`$A!6L9Yqk~ zu3+qG_J;dDZct6BH?aspY8wXmOhrw0{DGTG)D(xyruUyi)jr9)uyRdP zuu$#?D2fDPv`#jLu&rlSbaxRpFjCE~wfqQ`dp3ov--9=SjoO8?YaPOaj|!W#MdvCV zo8?m+wrKm$9k}P`GR}DZ#tulk6SHJyV1f37EiHK~M^UgX_J$9yKmXTw;|g5#=?U|4 zbzE&WFUYQIo#sV)@#cAxJ#_0smt3JQv(R58I$mm}Wk#6e!wK|mqG4TT>cJ)@B(WZmtQ9OG0*+SaNRePtt=HEwRCG-WyITU#h?YF#xcN$UUJ zkI|(J(xML{*|3O{uHTNvaRxZfWzw$R%+VhSkV|ehM=Sl{k_8ZBTy#Bfcw3U*7ocpp zSzAru!3=&Oi!mw2Db+5Md=em^A?E0xF z^NCyrEcxt z^|mpA;&#YLLBiwc(%d+h6Vc0i2SymRz{7Mdy3r6+A4@odpkx z-$<2 NsDpgA?gsH5`7cD)wLSm< delta 3145 zcmaJ@dr(x@8UMa}_rWg9F3VdUx-P5)A{!p^sEjNoI!0C$izGaESssm|D2kdYrbLNm zOngAE_K+Bxn53=E#OAR?Oop0=Iw{CZJM9=v|ESVrYV4GfcG^0Vq@mwA_kvzKlMCPF zcfa$U@9{h5e1~(R#`B{_dzD`{SOFpc_PjE%bike&)kA*|ywiJY2mpo#9$dAk#G4;w zeP~;IXnT8G&V#!ayYjq6-rQjRqMVl8V%L4uJ2ty2H?(fs(!HyDdwXZMYvtxv@4)+Y z2JTQv#dIeJ&3iIJLE2Jxb4X5;4zzqjw zKm%~}45{H+jt=qHVJp3kaNSY<*)RL1r>D7YfY7&u(&5K^K;f@rHq3eUp{E7;xef;@Sy&t-;_X839N@X!<*2%S`(IGcX^FD63kfT@l>s9_L0&&}`)8=Qt; z+F%FlRQ7hc!!_@olk9#3$qW^kYNrZTDJdhJSg9NwnH#m5$}o^_4M~+UG_uEWw`MJT zKkWN;J1(gP4=)|YU>zYzpc+EN1?e6kWT28y!=r?Z@I4rST0$nMp)~50iSsFPJv4-; z&wpa*ZKMGS4!}}qB4mY+$w`2a8BOpu1PMiAES1ts$R-8Q3L!$#(q6a;ErguXGw>&9 zB@`nma0S{3#nP&5g=Mgu(&4BbvM61*yav>0`LYjwKz1^$>Xkk47(oL(DksBwLPn^U z6JY}(6MP{ZRFi=wISx8V7Xi((6E+gEz<;D3*hI*RzsDD$lTal75gBYIWW&$!2y7t~ zg%j8hU4-mX0hYm5LJn9-nH`0MB;^kmopbzV*oOQ8`h{so1FIRhQu*)2RD%F%mvYi) z&4jJ6C+hBApzd(zrCM3zvs3+S$TQw(1nx_0|57SPDyC?v$ z&*ibl3m&JejAWAyl_Ea??~G$YKNLHH>vqv7-@snjt(+N4!5(FFY=>nxX=ycJkFw&j z&+>%$ihv&}M=w7Y-z#Rs(z$z5=&eu;mCBNFmwPYykzk*`dG~(YRy;t3aaq8-6I&8Q zXZZB^iAc4Nt+;m1Ec#e#-2PEJ^-L~{$TD5|U5uSg2hpV1Ga|xkZbX}eUG@j-QxYuz zTvWT4+U!bksU!U6Uy`&YIzBaSR^7jF`$L;REM&mn2sE5y#K+X=!-LWIj#JgHbz_;D z$%6i;&s?R$%w-|_Fb5Oa$rel+{%sac$g1&B4u&*1Cl9Yls`lRn=vLeFa7qcz*9^)_ z@ly?^`7kg?*s|VQEY@FZ>_ROTs)OIuVseR-7Pq>6XZz;*4P6gZ`B93K?_7$+_3RTr zi=tt2X$c#s!=(GaYXaRA+QTPo_h{`sGPjjfXPxY zZFYSAJRW(?RgSp+(s-?=XNyG+%Ffi`2oyOa!R9FS_rlMIL3$CmZ?LB zR>ZNnO&BAxJo`oe!*x_U7k!q0t5D6aSKE~>t1U{o-xPf>-Rx8oIexi%#xhRC6gita zKRP7QDsXu~mvc081+Yv+ziGO#@n7ozxabQD2Ds03mKf3!)&1+C^EVh)-U?^3uL3jG zT7#5S$2e(|Svg^qo&eYSu5qpMrpLlg1~t#RW}x%@^>xL0qev{Ns7cojbe0V)w;3N2 zHC=e)m}x(45iU78ql;7I&aF&&%xt7t3;ySXU(MNV1K^^!K6aa1v*-|Nr#L5s$#R_m zS(gFRy!S3e-?4wbmqm?_i+&?}j0o&WGtOmUB2yHyuW;&CpA&$~ode2`Nk98MG;=^5 zEyUPLH=Ag|1QuM5aqNwjnT@)Uk3E~Ej#0SGLTjPR3<{uJ+g2jTS5v1nqM@ z6?>d60xnrPBWIrK&zFskyJB^W10WMq%T9Tph=JJ~Sm%`Hgg8(7(R)Q$P#0 Jqn6)^{{u=T;KTp` diff --git a/trunk/lib/avi.jar b/trunk/lib/avi.jar index 5409c76787f478c7f2fd74eff04b4dc5308c2d68..740501fa061f979e426d7929ee8c1c0063ee0dc6 100644 GIT binary patch delta 1415 zcmZ9KT}+c#7{`0gQ)rb;<)fef)SnR zglsWQI9VjRC5SS;#iTR5*C6cVg|bG$Ths6iPxxQ0Xl{6cr^YN1J-Il*pU`Xs+(-*% z0#ZKhTngxMD5|+GFrQj8FAK~#$1un)BoaLk)hrXli{7Yb~pi0J-9Uy zaPii-nss=nTWy{=Qp6B)+&Ql*)1%=mC@p{X8UPvdW$A$W*E$qb4r*CuASNj%YM8kQ z)OV6~qKje)vDKJg+4BRdLPMp$hkdXFzLBepsWdjoCiT!R-ez;?u6#Sp0&0)RvFO6} z(H<2O>%YD$z8hvmiu*oWrbg=~*mQDAEV}KID{v(GpO5H8X^5>ArV28Nwh&8FI;L5R zTL0xNdx;$@&tI@#R-)&56VFRgC;Et+urcNLd|r?SEz!XT)Z5(j@cr1ml2gfBlhE_P z{HZgG290LXAUy3nLkui1t+){6>B@r|ZcuMGQ_s7Wp;psT{+rs}+Rpds)b8K#9R}1I z8p%DLZPsYA&EeenjBw$cQOP^UKQqG?yw0EC1t^wZ`SZ$XdyS0Rtw>Iie3v@pggva1F*s>Jq=d!K>5*1F2JmnO5>0v z+{J{^L^LBybQIIa?_#6zSTrR|=xowiV51tCPTFWQ;E|1jfcz4w1spFSA7HG6@Uld@ zohqR;*l7>owq2S{4r%_>50ShIM|(Xo-QZ(;hA#E%4=M5 z!ZsJxBQ)cpZGd%d8R~G;ekf1f)CkyEN)3RYOX(mW-9ujij(MmF@Rx@g@tT`k{!SGs z<&+^B%gBpZe;MrtB$dmw=5kqayj=DusGvG{LKUCh^(w3^=s)&L*bY>v|K`*?~xWLd< zG#b)`6C=@OV*HB6q{MeKk${3`x|n6z!beOLZ`>luF6Qup7}x&a)6MPb{NDfbe?HFh zp5A_AZ@x!RceGaCY)S@zV!P``_H? zCAJpfDYgcuD{eEDkkB9W7ad`oF;_zm=8BE=yurO1*a>nsbPp>lPAEnWcM=oQ9P8Xsa4dT1B!vX|(toETvtwa3JGeBt_d zkLoAu4%`=~M_8%i`GGA`qYY2kRC-1ty5(DUXn*`a@7Ifp2>V2ss>vjdL|B^AJ;gfI z`mbl$YwTEg^#{9AfS%_}e0hdC(Nb>0#*|-*cySiAR42cs-sXER-;3QV`8E7t8hU;) z`}Og8gGMuN5ZLV0Q>Ct!(9dYWzIh4PJ!+<+MyRV2YI zJY|H@L_EVRy31(Azp=4oES_Q(I=gfh+o=wwE<0@k{A{N%ps1Yc0f)=U4;U{eyeyIJ zpc*L64%!8{>yT!XQ<`@;sTQHjPTC51=alIi*V6_l14($51cyt`bIL_QcqU!4@+!BS z@Q9n55Sn(=7QkAM40U^GFO=Ur)B@O0LCt{c6|@hK?WNBFhrHAZc;TfMyymu!KQl!} z73GMQO7bCgwUTxM(yC-yTa~Q%xJvdYuBHZfBGt4JFqwoRpG=SVoP) zHL{M*PmNIa_~jOc{Bm~-0y6YvK(snB*>}`;Cqu}mZ+6;)*(zd?= DoI9KB diff --git a/trunk/lib/gif.jar b/trunk/lib/gif.jar index 05ad570016fc8734d8dda9ec551125e096cde164..8c6ec3efc3acd6bf33011e4a46782ca87e5c26d4 100644 GIT binary patch delta 107 zcmZ2vxX6$o}n8pm^U6cn?pH)EAWGO~%5WU%h@wzBj hKuO#Jq+GensnCd1OT1;H6%nXve zC%m`*rg)nw=yD@`BSol@_L5#^daTah3Cg;Ri qfdyB_>4E86aYkU8Ki(Eh`^Wo%=>_p&VESi#Fho2d228I@2m=6&B1Z54 delta 197 zcmZoU#Mp9(kvG7bnT3mifrEizPFU7NUJZ`fVOcIEnVdlrZ8O*m&2^Iuj3%yDW(G-K zlmk^n&;>F#R(=7$Tk!1E$v{gaH6By+bqr diff --git a/trunk/lib/ttf.jar b/trunk/lib/ttf.jar new file mode 100644 index 0000000000000000000000000000000000000000..651b36145345b7a503beb038b4a2d610c0e87e19 GIT binary patch literal 812943 zcmdSC2Ygh=wLgC5YFBr)x{_7`0iud#iW<$BZiEmZP{BwP8QXY~7Lbv&vLp;R%}Jad zr#TJBP8_E=#Yt>z1P+PgG^f6o-d=k0UiwRUdBw?d;{W$MbMM`|tGfdGm;dMU`(bNt z*|}%VoH=vm%$YN1cJC^P#6@Bv3*J7wRRaHtBqD9iU5#}u?b{mu{zZ}9e%ATOdgmM0 z{_AIuoqv<@=VxteY;W1t+}Ty%wyiBW*moo~GFrDUH9XRn9$Z(wynb0pym2t_rg13Q zb1YSjcldE_{qmA{({L&|n(D3Fa+>+Cs$X_!)s=OJm#?W_+%cT&=}%QRrH6;o!^u%V zTv8H0P}kJa*4EtKwXV7?**93%)Sny~sXp1)-(P(=Rh{hZP4!kMPmHDq@Igp7~&1^^x@8D9Rlft>4DGF5H#GOXAtJ4$wzHHqjrA0B}PlUoIj2d;}iI zM=A#4MevXwJ~}~;GB-zW`o!V>)adD2QVd(|8j24S3YBdRq@BKGL5#a2~C|o zFT%sELX`I-mT@`IwtFFS!~M& zTQ({w97^{Mj*civwBD4wCE0Ldw6DLRwQpo}y^^BNzN3T5(G$ZdB@1$X-q0FAYByo5 z--J&JH}nnmjc!s>uz1NnC6T6dFFr17?Hf$BpBOlt8tzJh5tLN4ror0#lEZy`c3(zD zkM#kQ$wAO=eF1vv;)8)7cJE8|jHZXzvlKO?WKzg)C_gzoyZ{ixzQnKnsX_dzT9jCQ zxGCuzP4*mbOAcv#G=*jb0%AGSEsBwHP6mTjnPAiLY{fT6+n zCkKx$Gwxe=#(YstO|c14z3B@SyC?O_5zLBX~UJzcD3-61_SBM-NbKupq)jqbVV0EN2 zGV4B>S6dlbu`asw5s6%sXm?fgyc9kvwk7*-kEr{f{t*i=5EedN16vNDD^U1KnJ=qk zHLe?w5|K^#eLgBPU1mV$luM1wlv$|eWLYe;We%WBm4#A`JB}V3eS|lnTC;%iT)dqs z*3(F$w#>6-KK@rA+LN*XKUE+#bovkqB8V$<>Q%65R?TDgNwrs(nprDqXRSCdF}FSi zsLxMw>$3)+)}lV^Q0#h;bscK8QP*cFekn(d7HZs4oR9I9F2;O!g{~uUpF-TrC6d8i zGN{7HBk!LEgWDanK_GhHWKaD+oqhHBUT<8%sBTp?cThNT!Y_h!JDRyI`I{8n86zH?@=jI@^OhiDsf95m*Uo%3}_BrBD;Wks|F8B z@>3Ul6`txf`U<#t%zXi5Aakz`bd+bw*i*o+P#L9It^wutfW5DgHPWR~Ayd!snYzSh z>V(hKlLAb=)~EQ|08^KU^>>-1nVGDtWEqOHWO+sn|BZ6}jmwzS4U68)ylmi9P=OG~kI$Zp6~C2A5VAuE-g)vW6#bM5nsoBztd34)&z>_w|k* zGb6FDK|~feQKmmD6`~>_#kXm~p)l2>B#r^WA6kr#l3%azb)!7`!!sP$pP3@zDG{C~ zFf}+>dE>BFe{8p1(C32H_UH`t3*&iX7NH}HTS!|6`hlj7X=Km?&0L0;*}3r^gI+P- zyD;-9CW|LlOgxO(@`(U6cPyQnqnvozU4@FA=jN=;Qeras;u)aS7h9Hu(<9n9*qb_K zYU+O6ls+*CeIX7?xo?zATig;XC#Z1(cJQZwN{5fa3MI8mFcnM=yWl~>EY+&muxULN z2M43c6%It-Ob0@DNG%W9abJ$VSx{FLq`t_F7*RPC&D6tnxh3bsS~}yL6kyPaKs$?` zlR}QqmQ*7(<48TEa4p7?255Q90Cl-mY|M~06Y9Wx=&|1Kt3@8}kCD#z4TeF5rC_hp8M*_A#zKFHSh*&1lg^4VhXG z%{m@sscsTwzN^EXrOT*y%h-x%QpI5zHQ}(gqV<{sSUWy!2d%mckQ7>Vg$r?$3$c)l zVdb{e4%De70ISf4Rj4_RuvS9lG;J1Cy$T)xnuf8A>eZ^jc&eAFt^ymZ4*A&1{djli z$FL8e2y#oX~+wa4f;W)uaE?OR7$Ay*^f#omA*1h=_6>v z$p_E_y94x@;nIgn-v;mw>9a|$b_>|z(z=wuXFMtiLbY?zy*>c1)Tei;Y(}pmyhfj7 zq&qn!?jxH^w`8E|aTk_?-ra=nNVhDWoxx5Eo<%n+FBsozQ{dSn8s2!GHMo&y$-U&+ zEzs&GC<8q%tc*UCanog#QR9};?3U4iUc`P>qA6P&4txNU&A|Zh5}&vwE^z@scM(=# zn=jbb;3+`n3MIMSo$kvr#{=}i9cVY_2zZ_jzD@{4Na$Ouoj&MkaxyQ|?pgQ|X ztWh!l&vjT08){Qt(?@iOHaI2G#oM+~*-+4L6l^LAR-b2L=b)~bU7svPbU8GGoEqa5 zYKcnc=rbB+SDz`9go8d_L!|~uiIh4Jua1)P%ml}!se@TrPH63F&xySh^$b+eSbsL4=#4;s6N{MHwsCR*am@sO7c*6^niF#VFWNah6ZTgJ1#5uu5oWvF`bIEV$#m z6y*co0%Gh0xLpD4D}C^lKJhAj;?0q2mv~u&r5Q2E1!l19&;Y$*+T*La_}!9u*<$SI z^$VW=#1awyaXiiRh;5K7Nv_poOEUH4nEX91r{w7(If-dH62-)dBPp;Imd9-KTQnwb zi>pFq$5l)fLFTDAlVV#rwknB(bDoZ=Qe0IT-zRui9*5<&f{&A8YBE7q68Mz3nyRMp zu8Mcl`NNEun#t=demA=apUjD=YFo{Xsd)rY!R+&yeL-9;R96(MMQU-eTB4RRsj*dU zTp)WR+TDtF^XTS0wAydL|p68SXmhDhm~nGD-% z#8wyxVq9%IlI(%edP!^8vYNZp)#YZRg&zY1^p}$4nd}+{kEhaCBd?{{--lCHsetB@c5}X&r9CU zsYfqMcbV$z)iUS;39k+rT17}95G8x{OU=bd0hOX}v@hA;H=xC$&L%tpjI_*daP5w^Isrjvt6PjTGqTH85ZpG+ z5`!l|`cks$NLLz-*?&SWn7S)SnMUH8T;qw+V`(sQ)_Ru9PGq1$cn#>6PQ;cj|k|U{pEnXsvwW1n3?7yMD$~irj zZ3Yh|vmu4T#w34mp%L2SDAN~f@_Z6LjB(|=t7{wkm63*%dsA>gffVaUJF&JY?e$RM zN@lO4U90C#N6?p!=$z=%!4F$T!M*sEbG)eTw6=T{iP70sj=Ei5i*k?v*N-{sB`jxd<~uV;neY5j1s}^9xyzB4 z%S&zbQb)Z^e(T6{&ayOMk0+g96ntKcOv9&a9}Y4GA~lEaMUa1`Jm?EzCq0RbxmDfz|vDa6bwgR z0-~x{$-mp`)sDJDz0g*#anx(o>mb=3^?LO}N4-JanLT6GZ11Qysy8|6&FU?VdaF9) zsJqnLFb+8KPx8->x?9}?<_ZiKZWn~BO<2#!9X!#WZa$IhrBhjtqu$QiyhCow#=@O9 zFS#6eIRpa{H*5DE^VuAY09>a&q(1DZk1)f7 z>LEuikQ4tP|KrF-AR~`4`IS0rtA`!+h&pGhF-Jblm!DXg{ z+EEwOqe|8`4-cn@t4|&Sqg6v_jzZ{HC$q$O_2PjOBcpVvJJ|=fqQUB6%6%~9N7Y3( z{KstdaYqqL^$BAB4Wh9j4DL9YpAWQri!j!N!SF_fJfAMB9!*z6sw{EjJA@HhKY#p~ z2#6!!BY>;IkZ{MDi9QGORVU$#n1U}NuKnqgsp0C;W641za7}avGf?qyP*J{5!o5L# z(ovsMpC)U3#!;VDZ*$ZW>T{0zy!wKpz6kyRSNzdYUqTjnmAu-KJLJ_6H381|BpbLl zBWgTnp9=jdOZCgsMRN5rm>PopxjhXX=fq%dK(Ymj>pVRI*@Z!CFgcj+>f@{iR;`_$ zPm$L6Thr7nVxwsz200?{3@$jisu;e>sNUPOh+ma=0uY=^xUjsj2!oK3su~qq6_Z0l z&@+_Og@7B6h%2U{;^-ya!z1bb6Qil!Nv^aP4jhNHg?=$Ttmk>d^kj^po#E=PGLS+=LC7Evtre=#p481J zFc&c@5~?$9jWX8f&KGDqbur3fCe8_9(QHqhf-V*r)R*juo?D$f%jM;82JSh&cd)Mq zu8v#!(>=!l27G}bzZeLDO0EvHgv=5~?OeX~8Z2wY{<7ELZOB7X6Ky<1lQ4*)ZNV^} z(iU6@1FBYXLd>|AW$+$vu?2r+yeix=XX)b5s?ycM$bZj(_^Y zl9A*sDNSC}%}O+5cEJ_bP@rP*wQiFqPmVTFg92>}Q>Wk?2(rY6wQksz1}o(#a5QJv z=TSIy9WYlOHp*>te`)}_BmgfB!#g}Tcn)1_M=FWVJa?jUm<6C`9v;4lx0% z2c(j3TG)-*&?vfIDmefkQ54w>5eHTRGt9&%6Le7H)d^7)fB~$B2(cfkQklNfCW9_G zxr5zkeaK9NT<@KU9We9zw0Q28fJreM?gvl=yTmA49*tQ}=aHbeM}>>~Mqv2yEFXms z70Lb)nJXt@JB8I5rr6VRt2W6(wbWNA(fSHK8CKpG>iZWVA2e)z4^>cKp=awW^iy1` zuPlDxl)|_}PESn|H*lxMr|F zu0eY?Zv#3`J>IR)do)0i0~PTLQhY(23sSOc>6nz>C37!IS@%Urz}ca^qGAm03S%-E zmoce4FH=5&r>Qxarj5@;dXt@k^c-9BDhvDy7Yonox^(21;I-HOe~c0kIs$L$7I%0-jB)b zr4@6=q}r{J`EBl5nFpLJ<|8q;s9Y;raDi9x8dgbvKdE9N?ses_I46rTZ97k|dc71a z{06Lc-HEl7H=)Je42Q%s(vIqk$lbbvX1Qt9ZQpjR!QQLeH`uE0^y+4<0#x`LD!OUT z9FxUkvSdGQiyq}FXe<09Y82pq6E|3xdtB<;n6GwB>R&P@4T1Y*?R9v&d`wp0vQmG& zE>Z=jPyPKJywdid^*DVFeGbT+{g;hnk-2e0k>Z%II zWb6G;r|ZU~`TnPu5cPsF*~ZF7$7K5%tVHR%QodPa?sx1*PitWl7~VRJl_rt*pliJ! ztMng)*Tw@_{Q405J3fLn_lM8~XTfQYpdrTOK{=0k(WCM$c|v|5pOYWU7v$gMi}EY^ zlKf7-48{1L;n(~%Wy#l7T)wHMU+U{Q#2pCcatE>ZZazES@g0ZtzTW*-99i?QYD!@!PSPyeESMMqaNT;?G6 zuawwRQfbSBf2Vi;L$;jN_vjA~+wutR|0eCWoU>)@Nhx|#VoyrpbibcKIC1g^IYFVd z3k9;Dlofm&dqzOQ>5-ZXvNOZNW?k=x!1c#q;hzTBwampRikd$v9|b_gxg@|5a3ih+ zTm+ai(N%V3K$_*;UxGNl3Vo+9>A@+fPW9bf5-#)6XO8Gu;7wn zr;9N?xlFfe8BGFi^cF2eyhzu__F}c6?MFuo+SHWDKc{xqcp`_v8XD5iCUp00)tNVjSSl z$>&|b+%G}Cp!d$q`FD&-XD;N)Qlu&akmEkearDP8=Aitg{E)kHABrG%XE6(8fbV}#|}_f;;( zksSN(m!)lI<$yQ3cAHVgFyyskauCDJm|O>mef>iKMrVjJ*$*(U$Gsj%)e>=316GBX zVrjERR;YSet(Iw|s7E9)y4)vU)s1kKkKR@CHBA7D7h9|jTfTlp7HfQCLacAd!TQiM z$9fg8UI(nN1lFs8^;%%P{*qXKb7HK&H8K^hPRcb31xVHsRuki`K!6*0zj2qzW3QSZq?z4uw7z7weL2I{+j zdMi-x0P5FV67}y+jQaO{)S>-q4sQ=oJ$1h{2C05z9O_4dZ;pZIFS8x?qB7T`GW$@O z{nDbYlQwljpfVf%c4+t8p&esvPCIPOY6n=&T+v0pN%lBu9i~6_Wn_RJ)YMUlt7E!E zqgNNZ#i42a&@}6)HeY zQKOJzC!}26A~V%VzjlD)*J-x=2%|NuHqao9CZV9u{KPGl^Ay05`Ch4PoT55Y8a2X! zIv0z&Owrm|3fBB0^$M8`8+?^|wais_=;FEO3gGepF_8WE_cQ!ua> z!M;9Oy%YWz?~;|cu2t`mM)h8e@E#Of2R)3)*>HK9CqI*)qY~Wu_OF;aM&bT69h%qe z$OH8JiZ%HaYl2?*b6v4@ZpGM-XK?r; zq}s6mjpTn+FiF2p>UlrwQAyKB7HV((jC-|bb>>~${Ze#0H^qHPGe)q|4~wN90b`t# zg$fG2g2ImH4eFzQD@8D^`ZcOWrrYFKYm-|oI`0~GVP#6B;BVX)_mEotS5QRBZ{)Xb z!v&|6Gc!D*C&lWsy0q+RrGonW@9xKR!DcUtp{ndfx!->!@O{k1QOWQ9Ic@O!MPo9Q z`~7!AzK_$UZOVu8ZlTddS}{w#xvlmI*-+bF_t@%4!Rlybv@&v^)Yer-S8%2?Cc|f> zqN*@*K}Psgx*xPRH@8R80^gW%2DRXOiUHFS^_Xagg1W4J1Qz_U%uzp)Me3(u!=Irw z{uQn9W7(p9h3&JymR;(%8rL1bXAW5JPnawe;`^(>jvoa)?$;zcM&OXYOtT}mytT@I z=xH$T{w)8AT192M{1?8k^k6biqEF+4LQIaqg#V5I$$?LCW9B_*$R`C}W~9gexb*l4 zO5#S>+ewf1x+i3`F1PC)cDr6=b*vV%xT42a#|u^$R~A>s?~_?oMU}-X);U#nl`|%z zXQZ%Tb?o+HkmqNWu`@E4y%l7fRAonMF|pvIp`*Uh-T0mmI&P!Gqxu8r_(#z3Pcl#a z2e|sr=rR8(JJf%Hc7K*@)RVGL{Y7q2f0dN_U-Y2A$td#PYFYApt3Y0CMKyhINBuV8 z?@7?j(XQI0ZxKYm0!`mIs5@8Fw-~eY4*3hH8iP>Sqg%wrH-oxGxU;m+6%do*6z&O# z+x-@~-E9$26FW57B2jsPZkqz#Hcb+H8t#e^5MJB3&GR&5hm-TxePruRN2|^Ji`#fH z`Co7PhEa}UMAZ7k^p8cm3lfccyCaD$d%L5FroG*TiLHCP?L_n5?pR{m-tI(UVmneh zu>)x=(So!nu@h-Lu?uN&q7|u=XhT|(Xh&L_=s;SQ*o`!ixCUu?Vh_@aL?_Zoi7up* z6MKnn>J?v^+74v?4KrbW&mz>Ey%- zq?L(VkWNXQL^?Hb3hA`OX{1$&TY=my?7POOXXd3_;MqiVT@mG1nbB+x1hX#lZoS80lm(6U^DCV8DR@q`Nn)y4uA54~W4K?(A;7ui?HB z3<}_Qn9};{pc}*;NFCb&%iFNaj;m3~Dj#}F1oa|)V4v606y|w-k&F?OHLc_ zjid9z_Oc>o;(4rM^{%vKbxf{`qu4buSTh_-xmJN}uC>Z;A3pWqp2LB2-zs}sm zf$yfm&9`|^#d0;j+#H8FWee|`Y}sl{GpPO#U>es+F}rfG!$$@X=7#HU!MF(SVkws` z;9qnUCVWK0$Xzhx$Mhz_!d|X%U%?G0pI4;6@)aInBj7Y?GwwtdI~zwE2Geo(EQ5O5k(sjHK^Mm!+3;2E;%1YZ4emfG#Hw;(d-`y?_p}3h+4c~p4d!YM z>pc9SjY+$Mfn_)LbUPSUIvp7PfTbxuoBko)4H>zIRd6+y|CgTAsB%R%`fO{Xe*Cuvj z!35g=G)%s#jBF#)X7wNeaaj(jRe>5$LIoy68<~L>v6)x{o24sc=3mc)?s5gbio?*n z2wDz&1+aQ#B18=0`x+Rh3!w9ubs}!9Y{0!G%d+L)!8>Yy`VkO;e>0IGY$daP@NjZ; zba-UL)mSdAcKxk4&O_|2dDW>wEUd!^VdK2LUEAu`%)5G1NqocHtsPBW-MgEs`B~p# zxHXJa@7}wmwWXUI%0|i!EhpMTj@8QOI@B&33rQOM1 zEl~)A`S?%6a&z@CqSK+?6kR+}>C=bUM^Dv{oJ8g8ckWIOruyeqk7)1uTj;hPfIF|j zE4v|6xc4gaCWFp#_`E)QWEu|xjbzVgV-FqA$0MboUz<)3m<;PtfBkAtO1q%o8}~~O z?Po@cZNs2yc&R=io)N@RIDOQ2j-KvM^)~nR!MA)@pNXl~iI_hVRQFD8O#Ps_l?}Mr zjRO@vay?VD|CJvr3^{{=<~AEeFFVhM(9%4gAU)>0URwXKAaw9N32}X!m&aKrtK!)^ zX)y6PfejJ;@Iz_r@5d9o%{ujCs@L=E^W0r@pcNDRqLxlCVS{B@t>KxIJmf|-VK}>Z zU!aIAwaz6I9h~rq=6P;g$td1#223UCvk%8EQ#FKjn%FTb*a%eWW648lH(uK_sRy@4 zm=eJ+&@{s+5Fj>7DoSS9k`ZmXj%lHN3uX=ZHVuT+uy8mv3W}g#fqBtNrkpk%5)yCd z-=x{!dsCN(89eCCCS%LsE$QRjTSu2W1Ht$8W*D5DR}7*PR%;)s`*9Y)mO*#tPzIp? zDxV{p575o&<5`)7XJ%)6WfroT_m`vtG4`?p?NT4U>n+IL8ioq)i_3x-*g{s~L)-!X zG|X=R(CcH3BW9|ZcmG~tQnzY$H*lw?w!9pyoM%r)nZa3$b9NvH+Hk!$xylw`4i#sI zdNigLVXd11<-nV)-obwEbq-=`yfTk-yw`YvZpZ8!9PG&6Oh;=Zs|jbTG;@}T+2q9g z0D`>Ax#gNXUe;d0-Y&j8evf{(Eaq}#F9A=CNswC{IdFL&c+B9)L4GhdjK)4rhDk6v zL+BF-WH#^6;dFAi7lBLj?RIhC%6EqYcZ?fh4cO2S{3PH;Zlq_{oZI6*6NM+$1Ff4@KbkQT(_#8L}7{J2VXA!RNT>kmMV&=0I%Fzg=jj0gG12Sp^$svV!+v zX%8!4B{lDrXyk$0b>PTAZB2ZN4z%WOO#H9GT5bm>{(E(C#=JSpFK!kMgeZm)v6@gY z43H=&CIwGnO|XKicaSSC8rR`hR%+5x7&l7KAXF)9hx;;j9gA&d?5f=WaV;3;dOY6{ zsOKcV;7JJeupNM1mMFq4ENgB_r%_$KzKz-@P-&EbN>?ncVXeocTvz#bWE9iBrp8Iw zV0yuGDe!$SOdLl8HJE~0LW z&>?tFKFlg}F}p1QD1%ui%#{YS4i~e@MCp@K=_6M;9=Y4Wxi10Zyet5dF;*ypT;wVM z4kL^UJcn#ka*=y=08j?Geeix7PqwK(W>dyv_BxR5^&s0D0{}zFhM_DRvuU}Qy)^(R zgIPEF&UnnKe9Wee$Lwxkb`LPSHvljMGmM$xm`%^c?A-xC8O#uEFa$F!!@8_CeLQCG z17`0BW*-ay48iP%e3;G5#q7ZVpbTaRcj#h94>cNNuc?^DrTW=-Nwns{iaD*m@LZ^c zXZuB|#+Wr1vSl7jsPl0dgD0yNE#C|LMi*`Uiw15<=QnaHy5D)x4~VXOG=vq(g-dTPjOkd z=P8M(C6J}P{%A>iHUC8w23tx%6JXX1DI8K$cxTCxjLm|JQ-{9&wxNG36ye`OWC+um z8i$5D%@)g%9HYf`T&Tj5)O1-xhn%%c*2TCeRV0YLQX~k41)Y{1EJBRUWmmu{dPYXTWabHTn2g znBfF$rq2eDZxizO&Y6gBl?mQ;|Ds;>R^w zK4Y=}f>>vz;H*R{qGO_CWHNZEH$|#Iwn-3PTpKf`?!X&L<_iBqj6L@L3*LN&-x@`6 zDsmcsgK`K;PT&kW6_~1-+M(~bQ18URL8vQ%%M(zzFG>-{toXyktawbEGcp6eT$GY- zJfD|R=;HTFjGL{>>Et~fv%xyZ+yagI6+oErZVN#^8-yzd(WZlBOEG(_LymeNvjVj6 zP-1LbMnDxkhG9-%r{Js*0oi#RfT{MaE`sxb#^->b#-_qxGpPbwyDEeD*cc&a`uLa) zY_-6r4)`p`Z&%{imB4Tnuv_ipF>4$iT^f%V@_BgFqmKMnQ8DFVo^3F-yJFgTsd`w7 z%@~0mN}?3miQ#?C>a*1Q-!ya-{*t()aE;UtF+f0Z%RusIN)H;S)69u@ z1@ei5$EgOr%B$B5dyb{kBRIQ=B*Pz8_OiwX&zdyhzWoXle?a5WWZ-ebui5YG6}FQl zxWA&=AkiVco$RqJdk3u%`o5tFH62a2GDJiZLO8)piiPWu{fM?f8&`M%27?a6b7YP&zW!MDPTnte)8;F>(sG#U6sj;P+Q*gS7 z7({tQ1|@hwMX@meW$O6DKplDL3hP(^iAK4!KuhchWZ)ub#T<6fX1L;Cw#2&bw-0@E zFe<`78s;Y8!nV_0!zsNenLgAvl27 zcvT4fz}T$t7~?#)41@X3HXXR{5SlHu95U9ZZCkSvlf13j!L9 zu~j&UWA3K(z)*TnH$|S%BLShCox@f8(T2KYwx=ooSuZ3^FtWG;90M?n^$9jUBnt(0 zIfO6fT)4|8!YQ_m2>&faT1JF3Krux)b$J8fyMPFDgj`J#-Ubi0NIUE>(RC5r7Osm{ zMW2u>s-S#FV5!m35BMt#!4%>}Rgm>?s4HF2gSl3LzH-D+yJ96|8ru&^^_|?g1L~!3CKcDEh5Oh1X6hp zv`6ZasKnDSmt(WU6}Ap1ZtGy;wl-2){sIg|x)I%LD8{ozw=?-Gzk5Zq2>+^)F~8`} zmetme5XC^p>cV=BdS6_V5qAftdObuOE)7kMR0nOg+Tw*_e8m z*GFRN9Isc4FD-vseLwt6zI{-XXGSO2S?DpG$_ zf9KuP_zgUPL@}{!D^mE0Kcd0#FD`qnLKJEt^zzRw+qPnHIcOEdECgUaXcgO*6SEM2 z`H=dZZ6N^jVKkRjW+4FcK@0JH4_Xy5YZ9-Mi>yj(N*u{lK2GCf72zTP^FeC{lbN7_ zHOsbU+t!@8Rc+0U%P^`XH(T>;YkpjA0c<=hV6u?O706&MVpdE`EDO_;gVsDIOPSOV z9406SEsXk>RUfw+tYu6z0?YXW#{YvB#{YvBUDK^A^(As2MSI4Z)ae1TF2)3}c6kAQ!Rwm81wXIn0vS0iFGYsA7pYJlk08k2HQFWDVII)k5d{TuuAuKHt#vq)Y#tC+}hgA4Hy{7vcn4( zJdJ>1BY=D!hE!{di;g##yY;!77MJv#X_G@i)Fp%fws6^|U^3`&OwyW~_gGH~bwT#CZy zk9+&J4EOaOrI$>6;LxZWlNw4v=xlSqoYG1&9V1-p*(G$%fkVUTG}M{!V8HH2+F`=| zqR8`5Lp?9Up{;n}5F-vzi@*n$>7(Eh?*(u`L`LoLlV&I>6axn#cyM?b z@P%nD?*+2-VZM&o$ljZZfkVcpj)B{}mnGx?P|bS=GOi`|wD)R;E(|W_S*KihzfQ^e zHGmO{8yGp-*pE>VaUU$g1+w%y^}m=BYZU_`ygXTB=<1mnlKzq*Uzc+ruDW3 zksCwoKtx*SDYLU&^NFq?WiyZ9-2%p@6%AGz_*Nd)PtcnK#pL9~crbD-ebQS&FwWAb zCl&+tLJ%WpahPW5OJZ#^Olp}8r%bx9niz?GP|DJt69~NR3m0@`#u(3f6Ifr;fiC^n zo1h%0rPw4yz>t1$b2BxeSj>`MW`^TWrPo6#LpWNfZ&2D$#Uae0Qrm{p0|7*)c|FT@ zKJ$x(_e^M|bH|1S`2YZK9YJ2t)!dT{#$k+rcv|rCXlt}>66zy{Of(q$N+SqXN%vAT zLiQnx?vad{<+|8F8m{80BN)&MdAk>Z;`O_&>60K=5#Q}GA;crR2QRp6Lxhf|(gO`z z46oSg86F_ON0aD38A4~}g76+6*z@u>d%>*BtuA1$7RW7(XgnbQ5^yqo`0cTz(2sgtIMs@9-6nnzdh(>XaF;y1qQo3 zkvenxlIFe=HkXEANU<)=KpcwKIB>cdj`(_!jnN0@cJSQ%(C^!{uGnTWfw!g(r`THz zE)W|TW(YM}qt!1fswkQr(I!)ePhbIn(c#N7os3(AKt`y|MSi?e=+5AROxgJy)x$Uu z%#Uw%1&paDxl2t6h9e3u|~Ix5@TC#$V^EBIXP$GcUy;(N42@T zL_hAq$c<$m&DF+xpMyB$|M3*U49AiBh|C;^$gb4s3>sCr4eI|2!SgIuva}`CoBv{{ zXmTyF4cYo)_@1JG81(1RdPbJd(IvR7=*ZXQ8yJVf^eSV?c9c>u6k!1oCIQb&B^xgX z5siL`QKC9&W*gNeUNJmo{!@O6CLc^!kGd0I2cbalYVuJY)Lo6EdJqo3Z=@P$FpOer z`G4!|<~NScS38K&g6!oz?!2Sg?IZyGB!B3@ipDTFs=B4Kqi)5r6)Wm??j}5*?=W&= zXed2An(D2O@74|PeO!%UkROd;VRaZUtMxwCAy~Ds`QR_|QwMR$zT?Pu<$Jbu)Ul3P zeU5dLb=+ZyB-`qDY`W1YaGb&GYtz-cq=lq_?v)d1#N?@Cw)JwydWH2$kEgQLZO3{Q zA-~$X!?s@ISg*BSXIn|fdcE}qR9_boh(qsKcPgymZVcn%+)*R1qHJ4lbgVb2ZrggZ zW4*+-bj+1bZf4jBy;n%ZgngBGjv=o0>^-TYoWncTeQbnxIo7+a_c+#j(S|td}4fHx&$8ULbIFxvuhTTOV+&4-%eIZ7^$%N6jRdkah32aQeeAr+0?NnNh`bVlDYGh#g6% z*_@wutS?w!#Hj69Um}IRZ2gmWazpNyo-*QC|7?8)3SSs0bWaS>LA{J9ewE4Btgk!P zH<)}=VJpwmy!#fDZ{yMW4$gMD{DVlW?^<8Ct?xP3zo5CS?;}A7EC`bc-91>{A2`+z zA>t4t@JkK?f+G2vd_1ccdMldGWI;4EZ>Y^e8JCmsQYAQR^%}rs!H}afYQktA7(9b> z2*^>tb5j|1MY|b~z4P3ZEWQLte?0c6MfTt}^5cB~Sq_cYog@11{ApDnClo3A+M4q| z0ycyBo|eG8S>o2ugikNAcMrq`n6P?~_07(2K=HQw0uTDigh#gz*)0kS9i|o&$JGCS zZ}VnR-^dwj7#x$YR$yF(9n${ksu>46r;>_y7Ja%!wR;d@)%(+x1`^1E6% z6Prl`t(dT3K}NR)l=G}Fg7U!iz|G$^I!OF#zp1yAO%FbtL`cHCwYny+WT%GL29iFj|8D%rQq@2wfM!2}iW# z;4`CH;T)Vy+iJ@rv@iUs>E|v-dXglh+lPtU}&v&S|aGCUXy!rLiq@z){v2 zu7s7b?HR$#!P4O9*|RV_u}p+BJJP3J2;z9ej}%C{Zefa}u^Z{Sv6VRmlDY6jI}cBc z#qd=781@wMI14)BeFD#q2cAEP=T8NmKaJL6(>38<1JMwaj)q`imrlXM zqRxumdW~?f_{MC#-Vg7?1Mn;CmcQd&0iz)l(MafmqGvh(MJ`B$J71Ol)NEe59=<=A zS-LqN;>XC*3IF*h&KJ@V7|tP#LPgOzc-B`GpF{Y8ijs3uy0oI~9HKr{l%K;M`ie>C z5Iz90zAKqb!TCm05kT;qRN-#=Ihg@yGwD-la9#(j1-r2$*iFyv;*|&?yIne;tuR@eGT@sz79LbU$5vxWVSYSs)*qVn*Ln$8KZ*et4v|0 zmTwAtsN4^gDpZWZ%GkOHJb?d1mIBjRjI%iV<1&Zg(0O~GOs<_(Giyw$AD20uI^Owj z+<50~0&`&0Tj9ic2CnUIgHPt&aPNE@I@mjOsU{-gQnysNda9U?y)&p& zG-O@@n*M4TU+I0#5zS_M^p1pgVZ-rzP|^3o-S_=y?GM23^+VVl_F?SF`Ut#b&mvC4 z!`Q=o4m%~!V^8x1xe4d@+zbhIE2PrxkVJPt+Pno4=3booN*a)?s}YVnp~^v(Yh;P4 zP?K;6>bRti$z7_5q*mU(5B)|}f|~3nm0~|7Dpu+{2Y0LVT`BIa)OQKot=4xH85T4Q@(swbZ-N%zf44<=8ZpWNw8mvC@4s49WJx^w&Vg&~p+VbCx1(Jxf9QArr#X{B~yF)9K(=47A?hSjJ~8I$#42>%A#L4FH%`90X> z5AX~BV*ugF*$5-zg@W1JE#$ac$echS;QI}C`Q>fQF3)Th{4>g9jP?J5ANqfzyuYAF z|1TQpsX)1N0_8@84!KIr^$Q+y3$6|;cuY2-)T^^gHqlg{W{_(f)B{BsuqLS}qHz~O z7Q_&#zbH_8bx7$j`McHT$rY4cTf<7%GGKFSO-19FY+-nni_+AM;IUhI4qH_%dV4cA zQ_@L(yTK4=S0V<^Iz&<_(A`%HYvlk_bI4K!gwZ5b0W2rU0(7i}YAWJZO~+|1vt*r` zffHM1%GGKPyrZji4cJZBBjUh(wEz%-rCXO7=&%bh?6JHl>I$_8TtzmVjUxf#x?3)0 zbov5YEwR;NTOkCIt!l7yRn>YmS1SRVHNVlTxoWLw)D=TrcC^-z(P|)B9+jOu!eSTp zad~9G;R(9Z>_byPh1UCJT06uC4%xaO9cN`X-dBJs*BGksRD$Vn;NJ$(wOn7~@Hj1x@Z}$dGy;bOCs}YyMP;Wa95t$DNq~nb)9pgB4paIaJsY|D( zsG;Ljv15Oe3R^7)`KD|E?V>wvwPG>|i1ibfb@Ft}J=x5v<%qf(mD`NUZILq71QysD zV9=0miS?O@3+W6iWIGDkfkJkokXc#>{^J&M*cDcl9xL#Q&fgVQN(V~WjZ*f& zySWoI?b4+fIacY?6~hDCgX*y>94Two_?6lOp+SL`fReNqv6c6go|gmXr8`GV;!K1x zbs$iQgbQA&wLUBcqav(Q4Xd;)9MVBB)O7(!r9Px}KBR1{N`Y25tV6)+#sI7gR_lFO z*;tk3sb3GU>J32hu(G(!=C;kXZrhXx+Xl+TwV9zx?_yU+(Jsf(F2~U>{TirglXAaJ z%GD+?Vpf}MR*itq0qYkK22osZsCfdah~L#O%E9iM+VgTpl#|LEN2|c6BSFN<3GtSI^UxVy6a{ex+_epQ0e-yC$61 zWntImHk{%09dz_15Ea|hcGQe)h@q!M&_Q(AY=y{Ha1!Gn&D!q-1j67Di$mE4sj1-;6Uw6WeJUN@m%5pK_&FRA4rTv!bF3F~QV31I5JsV&XUw?K^C1wFkn>wEZCJ z!$E-xNaYg%ozb$iK*WKvFYrn-l`=B@-QZhj~Mwr*r@+1ms?n=yD+T z?*%zDgG%u1{W*v6G8{I+xQLfpRa32v%(w@Ld`C-osT_lHs62O)AFLbIPm zQ=YpVOo}*~9Z=nF`I#UcD9UV%W+8e8s2vt1?x0J;eIOupiG+*ti`tjg zotGE8r;ZVho@%Sl0MXBaY@gHc%sy^Ud~&ypAypBoR0QKhK^Cd5^Be4yD3zrxoO3~L zZ?AJT;!4PumyF3v-M->JzAV!{w8E;s1pfFk(D)~)8DE9e`5F#D`v#P;Zw63W=<~}$ z7o{lL@p_y)CVBVsG4v@ic(hT=KGaLyT+#J$cPX{Y9>&j=jz zdaYiM$s4kXYBts4*cog)i&+IS)r!bcoR3vwA(n|%B&)5sCa~$PSGgFw;wLsQz_CgV zsheF22fKe|PWQJ;0su4JAC4yO$C+?{n$7Rb{k}Z#easghqZsWCI|U1$lKb(Lz{i=w z;Sl3~oHZm&@n{to60GTvrZ_OxnyDcfttdDo=+1@4Iti7-AhZSTX@;3cBnG~ouj6SN zn0f|p%>g_!M;j0CG*lK2G4MBY;oS?Rh5WnfqP($tX?ek~E8cWo-b@1&B4WIy4d+9? zl?Q!K#myOo$<|%%bvX0;ZI;~s^e-|3Ob;hO7WRxkW3qi3iW`9s0G0D;&puV`$g zmI9jI4gI98_M+Sa)#U9^O=_u^Y?^hKlw$e^o#Y*3a<3PGlj2^>S_`q8tU4*P>SemM zOscIFvcOs?4c2NOWfbC~SAdCdkrqB>2=?+~*qAM;M%SZSVx%q@`tQ=9=d-tyym0bD z9%=>o#L;n&8v?_&wGKUJJ$lY2Y)8LZCR>{WToDwxFV)C+;wY=zz_IBPCBHMQqG6ggzknUsG45qyJ@hp)&+z=Tw31p;kAU^fuB27+S`cH(yi zkeKPV1)yU3_EVQtAh%*!)rSw>C6Gu>fW$r^u^&iW3nUH#iR*yG_0Jp$_yD>{BR`)bGx)zFO>tzE==yVJ zcfB^(yasc6RLJMXql!})IG@RW^*Y=YVAZQ#y&iW_SC~a%u9;R)P?WaS8w#_S^-hma zFo_yMQSACXW=tM%3FX&+LV|@*VtX|30T8gB$O-UKSVRTf!iAhhp> z(7p#k`<=4UdXH?j-X&YCcguF`e(bYPSuw+M5X9TGL{pf6-s6IJF1iq9DAn>0-6d7Hd^k~bFDB=Y$Vb$p@*oCaDdvxn zd!-;-oEVAvF|_l?(Z-*US=J|Iq4im`@e=_mcneo31B84#%5@d7S(s$2cc^<^Os)fO z5|iq2R)N-hkqh#0uB!Dbjk!@ABQD?l2zf1aAN2Qk`RdFKT0Ia%n)+BAN0r{#fzv>Dbl^15 zT^&3PwBuoUq)`7-#a~wN7rs1K9>Frz7~Hc(X*sW_B(~>cmsON1e!qnkvCYzZwGTFieu?1(yRwm6%wlUexWCxQLOb`X}yJpBP z-nH_sjY&Hn^%os{+|A?~CVQB4GC?H8y*A9!QrOnGr=z1CQZM6qp%I3&N@2&I#`f*a zaO3J|ZP|xwVN3hgmhByQv3*Z-Gd?QV!E<&}NI@-HB_Tpt^ zht6cTv^TZxWq6FjwvMfP88{MQE0uc)fN zqPF^q3hOKCtgooHzM|&1ayo=|K)MP~nOWa?Z#1GzH$DfoSh?|>6{7lF2_Ay5*83Q? zAew2~tGir&nYcMop(<%Qz*w^N;D843)-q^f%i-s-0v-S>vHHJCpmWKcAmn>MzzbNG zd<=_;pMj^$7oo9y6-(6LhVQ@+pu7A`8sT%Z1(4SPz9s9k<>`xF_1Z&=U?Jt-5@g6L zPw6s;KWu`j?_t!^FaG_bk0Jj`hA~78at1A*$z+y}7aWsnUgzR~ZkuPCFZjnujfJ5e z;ktum@S_ZUcF|IELwY=`h^Uiu&~arH&J?y~AqCAM%9yDLVMe)vQ>F{+k8-CW1q@Xr;hgVbN8O09Biz{HsKz`h{m2Qvj-yJf;(>i8oqdjaY^T* zQ!@s#_Pc_yu^2pvb)hiXz~iMo*+3U4qozdR=YZ)4J~NT<`0-6(VJcHRr36}cw1A;V z;pSl?N8|K?f(NuG7uTgdM~`|;IU0b<3M?P3)T`Aj!zffU-7)|X9u6>@>!5X51Sv}3 zeu_+WknUDJbE`3j`WRiy4<<g%RaCDJo(i3#$)4kF$ssq~4YsHBq=$R+xKsmt2_l08LpF!Tvoc$os>8R_ zcnDAfLAV7U-R#IJ=Jdqse5WURKu}-*#Kf%lrilRIT!A}+PB-Cm}Jtl7PB8XeP}AQ!mF4d5`myVi zFcC6=ClEk|p=9MSV6j29U_=u`vN9y71&Pc9v8d+K-Ggc_S_MyBlB2Ajjv2DTg0%MY z#d6V7>l}P=;d@tT>>Sm|qb-1t@DZp?WoY8bkn~k(<+=Jd4F!7td_2)Fbpi5oeTQdp zo3dVnCoU8(D%das7J}%zgwAq2P0W5A2Z}>;gE2gg7^t@^b^p^pX2AuRQg{Wg!T7co zK-b~j8UWp(3$8|=bfNt8;Wa3%dw!fR&SI-@{DhKkR#KC$X#=6yVm3tZkhShZ( zTlKl7?okX^DyhB{YlIGjnE(@-28K2rhjG>dqCw^{h-6Urw4^xaYa=+CV;Kfy>=T_B z6>q;H+hS`URK*d5xd@!Sj-3UCSo+zF9&1E`wF^ zNfF|^^c^{k!>OejeF%QhoB$!dw>hkVot=j@fT+037vCGg%I*BiAl*EPM%A68=v*pF zE`%r1^|?~CXJ+L2XQT{bL|u@A$|#1*nbF{zLWr@M9Lp);7a^_0A1Q98pMgl=6p1fyikOH{B&Yw%bA1i=c#Hq zbS=Tt*%E@V%;ow}hB)vwmSvlk<%C=v2Q^?+j&dS~5XgD$o!R2K4=*2|Fd z%-80icUR$fKptA1nOxzni_@&VvWvMeB8P_V@Y@I@K){gXS-dA@CQ1H=c0kI!Z9y1? z;o%cQ2#gg7G76qRfl-*tdA$rNj9jG}s6S|9umub4H{&iswfet?^%L&g_C^od9vC)Y zhc{4rqeY19G zwG+>b*+BB*W1?q>x?VE`D6w?Lwdcg*7;9;44dKk^rgdn$#OL@21sj~B0LUB-o{a^_ z6%Hl~3lw7(*H>d$HiIPnG4L-lZ=j{Jsq|}~zY)LiZ!Uff8zf!BK+Xs`#N$aZ+*NT6 zwMv?8+8-m*q)#F(q-=%(6339@oB|pk3wac2q2RoMLVXx%9F2t21|nQLtrDC!0Fw^y zxNr)S4v(k883U80o5{7d9JJ*+=*kSF9yq!z)DDIS=^Qn^NRHOQEqXLf5BDKFNKyy( z2TP)-BLFvv|>PZQoE%zU+Zm6a9KyW}|7* zs`><3?xJTL7m7kRRszZm9#RQms)>rZ)cEq6Np2uCd;Cv97<%#i(k8R4@zU|wl)|2a zu$-tXE#8A2L@I|M~Uk0ZfMx<35%MhDh_!wyUVy$((bM%hQOnZ>nx zl0qH+2mCgh-`CpM;r z4%vZG+%s32;ke2jL{V}U&#*^i83sKQBi=h;K}J2-L;^A{h+y3eKj`uPv_5 zNzvseIBS)9XrKbqJ&qq=1GF9IJlgW)+Bhla&4RfZbuG3pa?lQCMqLb%Y6>JE<|lGM z+dg6Iw3gOB1})&CMBt_y#VJjN-Pndu`Jf~uw*W@rMp?@C^cY;xm z+XfQna9I5XsW>N-9ztnzu}s_uaa*8gPMa_rg%>``U5RG1< zybtyQeA9^8UK3_DJCN?iY;QkIk&Ey(4|{5Y2D2FEP0rsAxT7cUYB9=Fk2rual;`;2 z#A?88KLc&mqdRd>BzC#V8jg-@fe%8zAm@8f1~rBS3a-qP zvEizcNv;i8Z5s#)Dj`7g)%<3{;^-Q!u0g_gP|T+&5{IsW@B>QW=zk zN`qyT2F_Z|sJ~yA=?&Kgz5*#&%9hOV%sFiAuGNpj%}Dr1L_>$?V6dE=LAsaDN<55{ zhGeWAPUX3Dn>aJw$X~FEXz^6>D3=oT3^vLE+*?g-=4xWp9m@4u;x4_6h!cebX9i6Y zoEemm-L_nVj+k|t&E-WC#}O$e#1T4UaA|Qza^%>k4u1u0ytD7;=QQrA^_AnjLT8ylo z$R7)mG{rMhILR?oP_n@l%s~={FA;^%P@6s(AQ^K}L%<*y{OXxH!!2;35VNN9doYjy z+5eBbHvzD#DD%Fny6?TG`}XNhC+SYQvypx2&YloRLqc{)$bv~A1canXcNVgANIL90 z2m<25A_fobEIN*ge7}FyIp>~xb9-a^-tPpSs){ZKRWs$=n4xl|~wGHvT9=X(y zWTc!BS*H7(+|pqy7N#b%K*#ivAxjq*f=xRKsm||g!)1Nmp4{&RIVz#rB|^QVpE5@Y zS?2{JX~v333LTLIouCd6&2|GZhL}W`9YtGn88$&eBe9;uKF4tJR6=5;WRG56UF5hj z{+dF@=oR#XgUuo6aw#{#p2sGTFJ920o*_iaAxnaM$%N@K!~txT^f*N>D$`R}MA^x~K-k2!rHhQo zi*@8StpZy^M2|L5g`?E5RbhMs$c(Y%vyS}f+pCjUzs}SYQX$87TMwZk{w;)4Jq3DM zt|+P3=@q~7uH<x3RUK2FY_e)8&lRHawCIUv0saAw-gg zbSb|oUQBi@C&Y}w(yO{qqz6(i2hIZEC8^>DCB2kB z_;l-WQ;W2gTiHhjts-Z(L|&HE05ADoj&xxK1F)Jh*FbBnb+wMAYy*|$8=<@DP+w|> z^jBvALDYf6A!0m}LmUdP$0^`0BS{6nqt(a)aJmJ!`lqE`KUj2(52fr|ejc!3f&{Bj zq>1NZj80$}9l?;)ER9j=jjFz@8QBcK6QNR}aqA)KhHiy&ZGgUQgs@W=RHeEgJ%$&N z^I~xC^^|m}t6JonNVT~66Qin|T=P$*Wf?FK$r#{QG4}BYk9Om0OtzrTuAcT(n#Af0 zd8#mN#WdOUZ!G(tXX$VKiKr_#6N!B&`h~T=b6*KbMkvOd87DEpcwLAwnKctp86@Z_ zyM{Ot{n}q%f)-aSgMF2v-ItfPrh9_b6Cr5aKxti~!hK}_f#oWJD|OD{Xz&FQtffFi7pS+GLLmQnHC zWmFfxGCHks3`}VvZXku`=^%Gp#MNAd^kXXhnj~#UZ;COSOfxB94(rlfci!`}Q+k$z zNksvqtOCPfQNUk=vBtaU?inDmp24W{{9HKImElh;6;T;%%1O@oQO+Eq#Ef%qP(jUN zI||r^KyyZ_gj`aB*Sl2R7gB;Iag|E2>m$2&mEqT#v-r9cXqLNj{DiMcT2tk=A}!Wc zEbPtHDn}iXJ<1B!YZ|GR68Ct82A-1w4vM25@C^yf&;XNqR0y}B6L18gLa}NRPGn}Pi*?iEVW2l^ zzdV^x20CUYQoE@7qN&hSCUrC;0!g93+x|QLj~QZ)&Pck(PeJB@H(AyJ-p>Z1r)Gl} z@XGjK+g#q^{uFTEqrGN{N0J%zsT6=`Gh^ZnDbL)|&4Jx(;XTF3I}NPUn%GwFMmk&Opjn;5A85b@rk5 zgS+?aI2=WoE9&&xq#~^zkW#$?Q--K!NYsn^SCOH6=@({I(yM{qo2ugWuh@0l=C|@e ze?7II73(tXYbD4`;}NA)A@kgGcsXo4C2@l)m5NO+{-O>8tTIUfy|gP%(|fyY+%8%w z78FyyxIH&*8vEeYtfcx|LV|K#sH!?U&TBu=DX<9=+1=fB;QZAS*Ina6IGsai&V471 z_Wo*Cz6E&*9`pkm4Pl#MRq64JJnSQwEN6flqPDOj6lmeDWPI9I=D+^_5 zw%lN8wp^BG%OxgRC^5+rr>Tv$EAu6e)Y{px;Xo1-%Be`l>R06>()G|ZCVH~6%r1W< z?^)>xX^bwZYzN)#mu04ugZtWd&bmx)-Df%H?uDjm-YHaCH0v1H;>Ttc zLdf5HISqkh}a9=f*3t) zEtEM&s%Ga5a3(qoj2pYA05@pp+-H~hrLkUcUWT9BPZ`_7akWBf>JbGld5@>S<<{V> zkR10yY`hI7NUVcUPfa>waxj3C;mcgd=2gMF!P0z2KQALK5K7K^`bLF%`sM-Xng^jy z-|hmv1K(cchokEd#oR5pPkF)pdH1Q1Q_uL{b!QzSqQUa$MF*6oqD;MM%bB)<2 zj2!FoHs6?=I|^6NHRxwI<`!h|6MB0NRrv4w&mqF5#!TdUx6$e4I`7oftqq2~XmE zr2l|(Z}EDZEbqq2a<};?PPRX0-h`v&51M2A_i5LOuZLV5MaNBJ%yXn#=Hxv&(zS3N zYJ&Wv^O7!pChFoWrLa;mYI*0xxd|w1DR&m{GQjm1Bxn<`&LQ_`lY5aWAdsBeG`_~I zF{k{_WCvCMo@H9v;i6uoH!kFn>BK^4VbQM}Xo@YSYCd-H@`tZSy-0s5eE>^y3DNek zYMOPGE?4VvO`b}x)!lWvT(8Rwy4)C;n`HWVvmS1dp7^c0yG@td^RTt<(B)1&zEO8~ zsi3>{cu$_oo2r=uZ`S24d1l1h0&`ytJ#@cPJ)qYQ>hA4j!ET^5 zAA!EHMq>3}hTYk&Lkbwh+7t1B)29)y?!MZ^#lTsd8Cqy%d|(mD)!lyCdHWE+%YLtj z(1~du9B~;%_~S%S=(=*+?n4OMzJnNm-3tAlsNFeRc?LAUlgK0S+q$F?*vjcRRTaO$ ziA349l-;MI*c-+4TcMfB*5wEVm_$1i=&7-6QGl?A?M+#FqzkJQn8&9W>fl|~wd2TP zcDg+~+A*85=7LuNbT@v@t~#cKf>kYZeMVG{l^rr+NJo`T2G*H6IIT;<W1>!!4))J^X;U>#Vp@Jx447Q*S8W@(v z-(o0PL|nMp9z>>t(^Dc+VjanhC|{U(rb8p6KatNeDDEVlm^EW#eHEd4ie`>eFp*>G z>7`P(B`VU8V6Px48w2-BlBjW+j`WNl96=dBI6`tD$FWDuqak`Fs8G+8;XgW??kpzj ze;!+OnU0tEl#a679F+2%ke$`qh{IAj!^@$~GrGuAgPi3QMotm1b zg%xL7Ve%GUrq%b8w}qok&qp~gI@y1)>i{deBqPI{Fu&`>)Acm?UFq4s5kG^w%bsHv0AKEm8V@;t^Zj$jA1Hf9>LoV1W6*ZX6Q z0PsTHQ^-7y>L+n%m`VpvbCv06BKHx#GTp&lq&nR#=1)h)Nr;{&arn^P68T$jqYbjM_WJU+uy%0!HdLhsZ2bCAS zWD=+{4i-U`aj*!g4B}})m2oBrzT~e(9kfIpf^BcqApz$<^$feYYg(yCq5AElK(gQ!XG^-z`b{4x_H9 z@0LV;m(fxj_1M+)s``}>IHP7XW}36jxo4zyDU?>qaT$WwX_Htj+w@`s-nSe zuEK4yA6s{;%W#cwVa%g>)9Suw_?AkT>2P@qlgD|12AT};pryzJTFnGn!>V*HEm#X$ zuR|YueQGjwBt6iP^gu__107h7_{r3fAVf!k5FH6ZbVLYIPY-ONSNvpxPb69Gg>k3g zy{U&W**JhPi6OEHMA8)XC~6akh&0MOjmg%&tH0n?tp1|DtH0<~tRBk7V`Rk$7Jv|B zm6Hc6ylHygG#@oHlE)LKxvjdn`qM-+fTh%^+1t!I)SPP$8gU{v@?%=a|MH~QZ=^Ji<4)PMA*} zBcUtQ30llgkDJM_8mH~^bk~pycc;cxx-FVjMN;iO^uFIm=kYJ~Im;+R=8zd%k}{cXY0c#`9|So(=;@jx zrTD&TKJ;>GKKycO?taNNGa5(Sm|W>N{jyIVW5$ZTTg=L>SiEliT##9R)5%cw5OvML z&YketBtGZw|6Q+qJqU?T0#QdYNtX_CFgZzs6!DLIWjJ+!I)5mNbcM-QEF0y>%-L#1 z+TO2N-8Ql{;*gV8G8n%3B#0uxY0tj-vNJonuQ?dG=Bwk@^?K}`udD|3$+e)`m_FL7 zjVH&HhI#5vr%|I3%l-euL0@J74*KRmrp-lBYd(u*tf%t|IOtpGit{U99}fB!j9uOJ zJay}jiCK2;oxf+B<&sTSh*ka)+dn$ zqL>avh+CV~C=BU=mlLOXnc6Xz-LvezYv_IbP3@@z4#3>*Kr3d?KG^Lg-Ebn$#=bK! zyL7t{R&%E=2&L{a zcjpPE3xM~SHwETiyd0S~t4u^vGtKV6yfrXyV`A>zb~y@6yW0;rfl^v&G+AkiB}`(V z9^Mm0XWrE7?|S?OlR`I63%n$5TraO;okzpV4n zDq@khcPFZUn5IEC#(CG!`!1SyVl)&9*$NebR7eonR~V@aXV0B|`sS{r#-UT!lmV== zE9IB(0L!ihc-fJiJ39|CI;|c;z2D&n-hD?qxAPFN>^ZQj04p7ay=WyhGL{&}mGu zJ+I!hVaD9qbLY-jgQ4U7q4|*cFnu2)_y3a+rGlqJvS;{IG6r3cjNYKD2U^j0gfrpZ*R=~qsaJvW|=CZ)ul{cW{l(3 z&no_g&<*{!+@_T{>0cQOG0LPNJJXwnE{|$GxtKFf?t#>s#J`RcTF0>Ws}%Kh!3r+U zT4uE`g9^Z1)xK|E7m{pN`=&$)QH)EZ%40N_EP4~-ZL&;>g=LRD;Ho`RQy7{~o-Cu@ z!merRvS?6FsxrU?PfNYvTHaHls)JpJ_xR1Qp&0sjgUEHbwHmK5(a@Aslqy-ZCGZs{ zRpB+G42FTVC%Z8yTEELWRJaHcft-E9)qvgY-F?pCNq&apfV<$7zm0cd5roH$JvVZv z`gxa9k_yj|mLc4kj&C7)IYSAj!7EVM0dIFNrKJ1$B7Vfe7Dd#=E(5pQ_UVxyk)&(*YEY` z2w4RODvtnEdU8*6*;+NU!qu5@Fpq{P_tYGk0WeS3tb)c^~X((>R3C} z+3lh9_HlwEq6RmZcC(|IUE=Fe$Dk)inTjEpXi603S;Ohx6Ym2GsJU(1c~FCJZx`wSSNwnR8ww72*OS_o_wJ z+I@YCaQ7rbCu5#EZWEbwna|K>5F#F#hUx1bu^!tq;X)Z=n>0zVV|&l303h(nEuTV{YX zleRQxNI1DI-<&^YraWebXsDa>e46U;Np3dWw-z_X*F&c~##HcQd@0>v%pGtb@1*PQ z<}i8>;>>%QtZ#u4^j3t8_aTfRd@r2O^C5#SLY=Xl5_Y4`*ae+)C1qW2-VMj}2@vl+ zynTu{PnyReR-S~vrl{i)bUy7koBQrYvBdqPsWnTSuwq!T+qF?gyNNNRhVQ z?1VKL;J6(j#|HAXFo0XQ!;Lnn@Sjb|nge4^uIfb)Etd&mw@b`AgAc|vc3EI9$&n6K zazAJ=wuG%n2sK!(k{EhcpJzpWgeUC3qqMU9RO&2T%jsf1dlyxHJ;EI>I+=xOnT652 z!xh)zQg#;e&YG?a5C0zPEB$FnEJr8BXYS=kF59zXQ|B(}sudq%?Ja?MLHxNt>UjEM zz(#0U0kXD&m$ovn8NL5wmCf>Nb9x!*Qib8Bt;T}O=5?vjV;I<4J=EzkC~tM+TMv8{_O~0Wv1AWApYDO65YS6YaR% zSwEz~{L}aGft^rgC*}zvHYs=3Kl=~4C0fwE8a!m2EB0>NzvsZ__-k&-#P~~|FYQ;O zVBWq@#Z+?oM|rcm{ZRLLU1&<`VAvZ@t&~e}bt%sJ`JTxcNK z_I5pq-(@tV~>2v~9$gSnBED z;!Y@UOH^(ta2{HUxgV?sfw`7tfX+y{o!RqpMrD8iRd;tqo#C*-9omXp$l&(}GZ~xO zG)jVi{Xpp$fyo^l_GpRo`d%wcFRx_Fx1$5?)>_8A2!c7Rr!0~zv7k+Ci@vpgee360 zuW-bZ!zb0LCNe(@fhaYx0kDAgAAOao9{{8SNUBB+^0PD^D6KTbZy4yI-CeIc(vG%T zce3#@7>UEa5`3~|<-liBY58t8ogJUlifib73Y0CWdVklIo$*q+qU(s8@FfnE7e)s% zX}s;~?AkxerN^9h#fs=qR{CY4F9|Ho9`vjHaNqLMgrunGz>2S;12aB3Bv`j6UbxTh zsn#A!>H!qha1eFbii3>cU}|u{Z#WR`1x}CFP5zTW>!F^W+N{PpUL31hWS3aqe(>O- zuB-8d+uiAAFOz-h#Ve*=d@)<^@EszTv4J!&;^1W* zY7g$95nTDim2X_<>)P(#x4ZZ4yf1JFiZKKrVNjzqEuZ-LE5O~j(n<$Zwd^ol4+Z8q z^-av;E-vOJAX*dK@4b|rKvy`HGY z7iML9AD!pR?|rHDX?mWonf7g(toi{X8WSj1%ZoLG>e)y$SOfdBKgTT&>7P{g54>Ux z=^ct!szaC+>JVmofUBGC_6zBu=#EaR+H+vXJ`|>T8QgZ+a~uD+@v6j;?(&!f{=->QL8yO(pv5^fZsSKx+3w zUb{Ic;^CCCNa09umqvqm=+H!K#`aYjDdFOivSJSxrmdTz?ryih49tI8v!*PhWg6R8 zZG!!auhM{&?UH0+D#EG(B<%?SzxDt9R+Je(_Kma#&fxU!=cI+uq-BmWp?Qm47231y zIS9!5y=Zcj>@97&ZYnTu4Phg&T}|vQQ+#+}uh}8`C$#6S*N1k4#o|WZn(gcC z#?WrEI9#~gaA58m%kr@9$l>m>yW6kq9NXSK7LTGloj!Jl2t_=scXu9Ei5M$AVjgoM zS7)50clet43-g!UAwjjfEWuF!kNJLRes2EtWFas-iOWN~*X|4Lev3f8tbfd8qH6t8 z4P7A=!xe!&6q+BJABXm^?GEgb&|Yb;3L${6Qf2=e;+~^3wAb3}Li2Ct-vfJnXm3z$ zH`<#*d$Z6bjSzYT2qSzbUN(%U@~5$>cvbw1uv90ZP`>63rM5dXgPJMAu;l@dAF2bwUTzkNqtxu zI>LLq;JhH$7kInKO}&Uy8DN$c4mmKWy#sQ;z)tJCx`grOO5EL!)<^+dN~9C$v-*+` zv_rloO43g2fnGbgZ7AE6n}8=JWMSy5%%lM)g9Mbfm+$Qa)zh7IMp*=V*-6#0*{OcW za{M}j*&G8!oGZkS>3tmwI#DSK&81$i2Df%Ok9}?&m`QbvgJvhHKO$wo2?YG4)TvkR zSMNNp>+s<{?ub7{Dm>+SIcZT$Hw!AKClCOYiec$0-*0Y!l)_fzdh34f23`a)Ek z@ASYqciX@Lw7i;B;-wbYhKUuC8_62k#KH9z7v0M=Xpo! zxr67Osr0)jgKgB6#s2Aj+5Oxv8=(7T59D_UGA8MqS70Sz%nQIH8#bK3TYTbItVQHm zxo-M%*(Xf4_37!;pUZU2Jz+BID;H!MGt-}Y!c3fw`w`x>Wm^?MW=3-sXRx?F+0vX{ ze|rXBCf~zNysXq@p)=D79nVD0vj}15Vx(qgVGXeif%bAFdn=GouS6iciaVTiA-6n4 z9=X4t3zUa}8aJLuv%7&CDH(FPBgpY2uU=uULR>02@L7mVuca-gAnm=59F<7hwh@?{Uoc@{Zn3|^6ysJtRS*VVg1ktH%HFjO);?eX@_=LH>1s^W8Crno63*G|J^~m%u6E+}=Jhk4g(}%%dHWQyUL$+4B zhht`F^xJ?R*0!9i*^ZfEt%@u#Twj{LY(^=$E3_#}&aaZMySOh=b+2 zr3y)X9dgEcWRD||I!*+?=FnrOf>~#PSBt=-m0->`@MkCg?E_D`>8X23e?NGjK9}9x zHvaBFx|*YeJ?4$*b!I5%^{!X5jK?i*93;fQ4gDXdU*81_zc#^kNJ0by*p}_wPbjwS4U-(bIgo6W=>&jDD){53@B)@ zPuS4H@7VZblRi>GlO(6Ud%aJbYw3hTV8>y)xEu66f^zj$nA}_kVqOpa+(Bl5 zkDHd#LjNSyq-v+OphBxrUU-}$^72^_6?HcqDr42z0+R_aNx!?M?%lC4BanGBS-wOH|uj+Y~fa>vgTG#J#O+u4zUC?9{eFDnmE*&9%*S zx)~gN&Meqk8GJTi-LCr@|cGrQ+A6QfDZYI$`4`;Z=HlBlwLu&PMWCHqg(pg+9lk z^LaMfFR(d$5#*C{t}Ro!AlsOo0abNA>)*Jo zib9mxIs+5f$~n4b=475Rr^oNI?p`=V$=fowXCW0n=)Bu|GR*6o{frs- zFZA5Mq8|4P_NHI5oBbOz^*=Gx`K9@at#IQf^6LPksfezux+7WKzY3O!V67s(meLB! z=>Thz}$^ zaw=5Ymt05AhOYZEcUg2b*Dwk9&?U>w67y%=Nv~`sLvt5{u^aWluW=`<-=XH~3{0NC z8uRDws@+aIq5p>4!RXsjQWQEKwvk_^?LCwzkIr|uw6Zv#$&w2~vV=%;&tsSSu&52+ zhE`HY3i zUzU_VEdPvI&f=SCW+7a0dlgvxcyp$(WVzs4cBDavi;ym3P~#eFX4-M4&5k!q?L|`w3P^bJW^9_1zDgF6P7PCBOh`{`f`CCTn z0vwrN$KsX)r6)l6eTy#>p`A4$w6WfujN{$r?-&d1>35rNbEn{$x3S=8X=`TTyoz@j zPJDYkh0k7{z9t!&#punij{6KiY@iC-y2;;ajUM4|b6OVs zg0Q+R6wV37Ch0QSV_j`)GyAGXx?57Gto6((W6v_f?GiKHE;XmwWoYWHG#A=crqiCy zCUp*TeGNEvuDRW=XL;LTj@t9gd)e+jYB!nB+Rf&h_I&eg(tqDx=sI6k`&V#4@Hlui zCohkKpJgTsdqSRb4jXIHEnV%fv67{9G27p_7`XT1ljRQXvTSlw9fsyuHEvBX^as(f z4ri?p4uTkLssBjH6)d-RI&2IaHck;XUR=P&?=rL?@l6gBr+Q4>s6(4@;KvaTd=%iI z^a%gx$5Uswr3Z(8H#x!K`1HYpROw&s$jKQP-EV zt0~vDFi%d9SvmRH)l}8BFl@>aM!yrtv8i_G)n^W-O9?E z7tE|mO<+U-T%mHn5+4TuMuX$`tZ$jYoZR$`+1xUNIjS4CZ210g?sn~!XxUzc=Ka;| zde@|uk5S3;F)CRJM@1`P73Ulg32A9TP8`WeqH@Ptug z<_Xg(I;btzDptw)$IS)D%oZ2`smEZ8BX|B*hgnbUxI>}6!3={6on&t^bGbj=-s%7s zqhlDx0e@qD1s2P*!+${kRB}HT%2I5mYV_>?JEDCSCJkI@eobSvJ}xxBAxA|*=jhF^ zX_h}ma(4QorqlmeJ5?*VZ|ZMJk6NBoBV@{2R0HUQi8xMkGAGzUZ&a&r5ccR{P zo5odV^u{{3z(qBIRIB}}<*FwT_+|-0O z9I@R?RLEI^-mCJTtTOM@?^Aiu{sX#v5U+fB2J^#u{gK>~*HHog6bs-h808_qn{x1M}vDd0y|npvxEYkY``g z<;!~fijw@9?!FqBujL^VzOIKq*X1vC`Ab#vf!q=Ylb{OB2lf81l<^z7`=%~`t*n2e zyT1+0xANd1u%B-JPIup~VK4ZOF3<hei)b^>CHdt;m1n) z4}tkfVE!pEKXn@1()n`wiaq$mEVa81_HJ{6T9WT2B=pYqBm26~+jDhi65Y9yhShTt z@SZVcUU*g{wKz$mt~`6cblhR_4@|vUN)df&87At}{Z_b+H5dD#%$t%jIn}=vXj7rj znCRYmxn-m!JE3Rc$;M6Hcnx;a6R)4OgP;Io%Zh0v?}(D4QNQQF9_*Oi*r2yktZR)- z6KikD+GBZLH9?UM9L6B8)0&gCESK)wi5?L_e-9icV&DG$D?tOXD_6=d#q!(IBIy}7 zUVu6PU3I&M1%MdNw5MawVFC}(!>6S%E%rc(UTPopOXg;GC5Gcd(^O`#PbxNW($XH4 z1JoCHw@WTOH&v(8hAnMgtTL%`T^ro=vDt|SyzVwlh^n> zu0(6FhV9Rm;8MGmrS+Cq4kU9gEvngr2l2!%1#i&<0IAosE~IKA_OC>r3-Rp%Trfwi zuf&^b!3rT+HWN>!{Xl8Nyx`a&0 zmuR%$l-Q!UE>1UaH9DC>d@y2gvNaX#bb2y&>Csl@mC>+g2M)~7=qrpw{K{Eh3LH4w z>zJ3S3DLk>w~-ba_e$8+6sd#N#@bbpDp-Hx#lHmR=OKrLUxcs%f6*W9 zt9buYQU4Y~$NwsXUySeLixsREsv2}p`Y$m56+%`2I)r%sABDyFZGfH-+`r!k<_{rU zk3WW-W6`L3(fmH-9E(a3#%F=82yLb8TC(~~ZWm9d+gugcT*&9D&{kVw2Hs$943R+I z5!xC{&YtD=T8BbgYwJSTbpU*`0RD}w2Yx#^H22scA)FrIcpJ_%>`>A{;@;PTew}Tw zjiDW8hl4huZ6cej3XGhvmp&f0YRZn_fg|I$Q zR*9lhq%89?wVI^3;h`$l(n=f=rS#Kc7azG!uz4RFX_1atN{j4es;I3k-P21+jQ$bQ zez(LaUb&%jgB$tj4wi3Nzj?#?8xh_Ywny)s~tQ?Dnq6y2vQJL&cDJ#14xft>EM*p_W{Aw^$mstG+N zqohI<>OObK0)1BF4@42whz(V*4UJ~x8Rdw_L5I#pxyVsg8`nFxO+EF1CiiNWM%#_2 zu#&ls2di=*q!$E7S`8`67m+9}qFejQ9wVGwv-dBpFkokSxMCbgtwN=QeVVW-;8t0p z+(*Mo^dG^fSJE7~3UBz1jFAVOv_^W0ya~|GTkpbdWJLP)s1-U;o5KDn3%-KZt^-hj zt&8ZV#Mo|n4^uZDY)5THsX<}s>cZNT*X0Tny;j04YmPi%oCDiI5ptVhipwL0f7W;J z>B2v+h4onN{B6s_wv5=lKG)$`#iVseB`!_Sg2=Anl3SR4)&yIpHD!@+RjpH8?CNO^ zCck6NNw1qw3dry1A^onC(>pmr1s)>|I&bw{PlK0xIvm?YNEH?Xw!G^ufjPDuHHsB@ zWRW)9*);AP)`t;UX{UdN|x(k=X*k0D|;hH;YhxaTy3FyhLT4f zC)6z$@!wW*NQ+R;o8`me41UGPtVU}n73I-rh}Vvk9A94Q(T)s|gE*cpj$x{uR^*SPVDrL-@pP`i z%0Z)7k7Yt5T6m|xouA4m&*lDfC}54XIJi^kCXK5`y)EgwHshTvSCL+h;uY6y5|WGk084b*!xHQqvp@;U~xhM=>*y(7sXWLV6Gr_4gBeI zfixPbMm|IQM;$#k8Y*1Vi~ypMr33Yb)Ie25)mR-FqWtHOU+hV+5-q?{IFx>xr}R+Y z!| zfzU+s8a_EG*dlMfE-HE%1^a14bB8dM#ug@|FZq6^&;zdIlc&)2XbE5^rXx^P-kW$5 zwv0wywH1^c-a6W0BwD4@kDGB$kMv&(1L{@i-T^Wm1sNYkI`R(WBagc3wAj>xghD`J z%IKs?qs>hqn}&5Xh_Hz&6%kx$=Z6)yN`EjFwwWZHu_DOUxMY5Ek3V51tZk*m6AP{N zllxtOB4wU;r&=6OZah_iYqwIKMbdtIRPO7ea))ZjrSCRG>dOH)lMC(ikt3g^MNfga z??;09!Bho9la>u-Y28A>5poXUmXl>vQ;b}>R&`|oaz9RgLg62Eg?i-5C57gqLh%|C zb(cjB`$k`?tphLQWoVZJeR1WYQKO$=I^rUIO6&WiK2d#p1-cNwXc?8+KKdYUwZLR( z>r}~wrtWCKSZbjpNUeHq_0NHJucmBMpk1x4T6v|IF}=B3^TDsCUOoGh0ELtt&8cCC zKbpDsx?rDYn>xYP^99!LFET&BaAr>;XVzQ8g!o4Gm7G9ag~Z$&V;@R(`a^3;nzX+3Vv(12##_UJvq zeTQa$mm0s1s@p#}g^p7Z-=B^K!0Sk<6?!^f?`KUBjc^Lmz_$YiKtzxa=DRd>Rjpx= zVAHub4|Aus3^J9~FPK4rc_c88{?56nf=d#$=sOgp<>xHltF(xgoQYbeYnF8ALDWT0 zn9;55EsIZ>v)VG#g|~Yj-0305t@Ll+O#{?Q){W&yr4&%YX#;-9y#4`vAR?QwvvELa+Htkhi$@(q*!$TBcOX^g)iY@@A7=sfSg$C0l*@%6qn65n8^% zu2yYLHP|zrt0t~h5$p7IeO_j*RrYmNc4L*@q_mr>?D_h=Ah25kdtrc$s>$r#CO^?- zJz;10wi9!r9PYOc9f7-sNOmXeC+@2DZ#&?;J+leo;I(@HwyS;URi0tI@O(}Dj8m-k zj?1womEYo?y|I)P@)pa4HH8rPmP$9hL+L>Z+vZ&dN8Y1`6uXu3E~O$_=)h#FuY%+> zF}bU3--go`u9DlfZ`*Tt1H+*(szY~l9gRF*I zse#a~Na*a%YvJS38%vYPTkE0<7oHQ@a;PyVyqCRW>Ipt(;i)<1QYFGhw+kU?q(@$! zsJk4qKI7+8^`65U6}?eQP;EE9p!anq&-i1DKmdZskQD}d!K8Kh5$556$jGuMQ&$<3 zzdUnS7xB?oLN_LfWJka{n|7)BoHY4j6e?e0n$PS~x|YY9JK0E2VPIMf ziN3+~vi#;A8xbMjh65m#lqe(?mvZ*;;B`9DTvkvmd2BkF zsm=zx#&1F~fM^JKbi{LIv3AV>nc)4^5}?ARhdSFK{@50senK{iX3l!NW*XE5dxbM~ zhUFl2nVOwP&_Y^$;A~>Ku#O#+j#y-#?pLf$*Z6SFYT^p{qfZGM;@z=-njmp%C$6YE zQ=X6ZbT6jTv~QFl#q_m0EtG+92v_Z32qOx|6^C`X#@rlo{=SyYs~oxR@YbU?Qr(N~ z>qC2qz0|o432nRG9&)bwf!u3+D72U1KV(4ON;;IQ6K@@MmxaXZ+tEoZY7cPf;rw=R zOeZAqr&Z2g!ErBcJUH#~xZmPk<$&$#mqQQAqEo(NuL$iSTzQz$#Yk2nfDCQ7LMn5# za`6~qzaN3US`I(14efRE|M5XValPDu++c4E?M=Gej4NP!E8pyGNfZY{IXtc6P(5(r z7(&c;eK=ELMJwyDP$Nod(i||Kux|+M9rjK+lGz*BH-`2uDz{~-@W&R?xZ?nk!@3;6)dCPyb3MSw94 z?ZX1;dqU4^>?5Il)Y61~f*D^mkJ)#H_Hp~}5S^4KB1bCkp}*{VnR_}nRCeirkkRo# z?rqQ-%(@do2#c48-rZ@$C^ZmmfPOi5s7r7t5`yB9ui)*WH*sV%-Q4_sDJ~+)`hO_( zNrD5AKK+LzD-Fxtp2Mr;g%BY*%_v#C2jsV6Jj_;`K)KB@KJY%023p1m{(f_wT}?j6+5*VUSpSNxYKTNm9t1#DUIhq+j|nHEUm@ zw#h)n#0iqQG@uG#<(s9VrH<&xx;P2Gx0&+t#wD=l z=L1I@?EEuOSy+ky(~BD9Amc`)i_$fKN{`BJr)-HRnx$)yEh(J(a$XiEYiBQ|S%D;A zJ}mJzq!njSYVjdnWnTzu!c+x$vz^E{1jXR z>313?tAv9_kX8W2i!RP7Y3phvCTkEHolF0%1IYCbEH5}eH392X#G8j)f1Zi}@(=*Y zm`e_NWR1zuB?9$Up42lF0HW?;1&Bv4;RH&3h*<_7)iXCkS}caT0?gavc@2ckhz_La zaUrsft;9XKh(5Xmf$pV9wYH`DYC;55Jp)CwM=HLDl8|Us{XtS7iR!$(4J@!rqprL0 zS<^r_H9AF!JYuS0beNPTP%fy|uk;E8vmEt!kk?O_Euy?7@M5HYKZ>R#?}zYyG+q-H zk8aLL*`hfk(e{{F+2WLAW~`GS#mW{!2d{W@8O`hf4SZmriO2+7QJ0vppw+_-9C^^4vi#(xG@>M8zUKC6=mEH zHp{`+cm!?-$$Jqdo)WobTsICjnLn5_1M|@E7m#rT<{eVfIEos^o?}-i+sl;fM{HpK< zr1Ez#N_U}wa5t(iZ%RSYl0eZC_3bFuj{A{2R=9p-?P;K$kDGT#t^GN`Xb!Jy!I8nl z_4V}&GA(H5pdo`_)jv)1PrTQ+;YUsAymPf8f_FDAvW}lZ-euC; zsN#P5>j9?5gDgF7XT^O8$R9=$_=s6R?<_(TxeB1xB0Llxd9%!QNo&^e{yl&Upsrn# zpP!A1_kDoxtQi@`45hc>$K)w`SW|D1$^6k^8~J|lTg#ax0T7apW7GF>`e{+ucQl`%d*r8Xsj{dYa6iK*swiSBYP<$0eOM4)-#`ZgmC& zkMkxJFXAb4B*McnEhFD>%*=B&>ux@nfJB|Y1x1y5+&j*U{xm)QS%lr6V-bALRqSWL zn55z{QN@GNm(Z+Fa8E{@Ff_PoD?E=DXr|S%S)8_Y$~0Ufe99~=?ZoFPXK^e zl8IIqO*E@Om{IBJQ11&RDEB+7AKoveMnx_s{7y;$%_#HPq}D8Tn-|M+TWJAbO+i$h zKvW$~I<5Qad#O|qkTWVY!8wLCkK2@wmH_n^DWD2C_e@Xu&n(UV&9eF7f<^V8>fq7J zhHk;f&0-vol%oB&QboioniUT%Dx%P-=pvM6{!S`$p;JGT%$duh`n91gb(=0X;CzrF z@EYodkpi72p-1uWgCPF^ivNf$_a9S*$7G2RyU|ouoy*4XBKJ)6hfD<*t?17tn9vr@ z>3X3VRl4a4vXzeMKc%XWmjI6xpG_LSoKiLCrFJ>`xyK^7)eC-Jder)tR4Fm83Q!1= zaES_lyT(-$V6LVmzf~;_W*L*Pv_pTHDyo1G*j-2YV|}~27B=5l)d3f2@&o3R07s|FC256N3{jB)fy0m_$=$%s%dPi<|R-E#{!_F0kBYA#kRf&h+ zX#rU_5=)?Viyn-{k0ySLCh^>ghKRNyY05N3ixbPtyW+@b?j`v?y{A-oB60Tjd93%+^ihA?@oEnb4&j!w;qozr2^>7 zYOJ&B?GQ5!M@lo<)&;O%iDxHZ&UVWX>^x@D{ppps9&o;jMVWe#z&@)}3zbSn3-`6uj|xQZGhKBaE#%ToYZ}?{;pD5UMlbp+q*}!^JKIdQ=c2Z^HW`u;&`Y>;psg|jC=AIklc^eAc9BPp5cSMl ze*IeNfNdyQOYH_%OEE!LA+bV~|3Ug*`Q_S|6Jnkp4p;T=NT|z@r_4O)lzQCTG3pKG z0yjgSF&F9}ruUW6d+DdncJGI10;CZV7qoUWZb;5IBkdM5&t8Z#u8UG|txdI=Q$k&+ z?H2J_1mZG&1!65V4C-OEx0j^Ki|Ng1jjvgv{7AsKYWqo-H>#)d+WRUG8DCW1_6To= z(Q&mcj=S$jPLr`a>5$#{5xU$};5+AM;Mij%H<@_SYXl z2zcnfLf2~fUw{sN%V9mLZkUz(}Gz62eRYl(o#hBCs{wE z7z#z2i|+I|ZMj+uyi&boYm+=%z3}9+vxn<$hp!fHm#y4i@!5Er0jB-qztb zUfqVF|0<@C@P_46Tivfvef8B|6(Ok>bGRz?noF(kV<{8whX*(5v5AP^r6#dE0@+8P z79K@O@m*$uecVj7{=n*Sw|GI1c|hza1VXODAyT~9ECd++YaG)43A1>}WuGt?4cYMt z(=nv;6K1C-iiM*RQ^B+7%-Ni|=5V6b5#qo2Qepm^9YsbJxcWddb4J>&&_vt{{dWB2 zx9=K>wmg6RQn!u8P9^HLL|a{B-Y*v92Xw(dPn%o{wV4kG<|BC~ATEU3*%O&&*_2-p*C|uIiJr%YJDM)7ojHer%L@L zeZ!Sdn_LO~nfak)waJfAoBRm1$!SoV`9|)n?~MEX<`pxVa%cUEzsbvO zoW9{fsLlLsZb^0gzD>@Aa=Nt1O;ApkZ<=rG?(g-E%csqE^zOU5;9V#u??O5AeNH7x zfLoz9^TTSbNqJ2_J$_w}|D;Fe_CFJ^*8Gbeey+>ERx=@fsk?tu()X*Ze-F&B0`ng( zR#BqHT2|S$Sk<)3{8#T!AMYp~jelREhYli7Z$;duiQK@9L+2nyOhM zu8KYWU2lWNWOvuajxiX6m3H)#6FqrfD(&BVaED>X*JK@lu%>uTU9t=a&Vx7fX-Y3 zjfAtwL%+r#HGy9HWnc5ffUV8cM7qb)nP)WVXMTp2==bTP)61>u+Sd{3 zJ-^cG;;Fug)ORB<8)Y==;yg2+??g*MGyEr|ueUTHH zz7^ky{}9@|tqJiiQybbkJ1D?s3|f*yLR1KcdY>`Q9SjsI#owpP?dl{<2Ln4Sw8L#v zD2u-kqV9nZI{Jj5~n-#zBM(Jy|9`Y5W3&Xy|YQ(WmQCeZ&2s(fi3zTO-tHI!SwA>rv0A66~| zM^Y-I>;>JWoZrW+SBts%;TeGI1BvWKc0wg~}bD2>&pJ%JDx>2G8;x z6ji7qw?{>uN0F+oUg}cS(!la9EiLn07%->7YB?PS%vx8b=k`b+$Ty-MWB$u1HTI^W zZcL=T#~m}d#`E#iOF!h(2Ga{HJL!&{G-_85#R~_8XEhE7g&@-E z^TppnUUivtcPe7t9jCLR+1{4Y;LQRhR_T$wa|ZZh(O$$7b7VI;3f;d;2P<5`naeA*Ca8<89eO}89XjOFb(yixEo{wQuQh)SczSAyj+-rvd~-^MWB zLD#<#WwN{I?t2^{F|RhBz0**jyoGAj$?$4xMsa^@(#y9pU)8{wR5G!_OxkfygPAgg zzpmqE+TL?oraS{a^a;(ISrFd>ByYn3%zcPs??;0CU<#UH4Hl22zu`J#9aF?T$ ziD=hJr*S2shI>I0@!L6vM%}lPUv-}Zaso_Z(Rl^r_Z{{jvVS<$VYLwuik0_Px8BOt zNx4E`VO@3w!Plj|zG^D~s#G`*uyvoa|OkPp^G~F9j>0*AyRn|~j{Rxz&1cH7`D*hZ5 zKS#x%M|g~S= zd1Buvdgu3`9DC=Z4Yqp?%8 zDwfPEAz9?paHyLyq6Fa!MS!e~P%u3U=aep6|4Nm=NTFJ}SqQ(Wmm+7C7WpfR{EuFX ztY8(AtnMlFB_++PK=k!#6w|5^3;j&L1s6Gz*^T?mO&{G|ZH)eAk)fQ;ZEQlZ(%Dd~ zYTto}@N0@?c4mbHt)~ZOp%$RFJQcSE1~)HR{hldTIQ%Zk0|vkNd#TYcE?;VuxK>ed z@cUA)m&?R9!ljC<1x{62TXG$uSEs?@l&;fv1YGa7grymK6jBw-Vi4_|8JRYFxzfw< zrBVWVtv4mSa9vl&k$s$(C-lZU@QG-!m>N-*<@?$XbBG=qpC+BTiF--9x~TNXy0s71 zM3jnr;yqm$Jw_G8MXf%tW8aYuAnldQ5v7WYiXNk)B9FWmdP91hgUjKbk25-qyo3LPhM4= zlqMx5$M2$&dp68Z<6cezAKdM9u8?Ei$i6aov|WAR%C5b_n{tDlEHnwG_G;z5 zGD4`h%yGSz>G7;@mVM07P@|Uj)hGcPceFLF{Y@c3xn(C= zOSSHm5Np55Q|=wr^uV3EyfH9$<(c1i=yJC%_vCr~CSC3osYXE5x9In+dh<42?nAX( zzYpL&EU!bqE)VMsck^^N*gTS#g_|yqRg0?E-Me*pLYMbcLry=b#P8GHQz`)Mq(>D* z4wEStpj=P%V(7C z*+2p02+gU7&jseWzLt<*mTrjFHtt##uW`gBc zujt$-Ri@lE(G6}JoioSiF_s&GRag0PUJ(^93EUhA=XA+k%z$02y{0;MC;OCng}kX0 zsSf3xkClklKhrDf?7(LF+j2x7_VK>sUPU>hteJTk@;R={xO7&^b^8(>hn+W17-eM5wH}hs}DUW0YD!R z&MPp#biSiP>4}Fhn{d&Egd;>_n}}T3nj54Qg;rYMhnf(<0r91Jj;-aVV*i6n^~;^q z&_oPfh}M{vJV#EZdXR^gbqV#798$@ph<62(!NViM?*XW!yhLS^|4W4VDX*nY%+J=} zXB?Loc+a94@8#(KI=!s_d-QX9(&0+$?VQ;&f8fHH+AC28 z@vnWf(E<2GDs`un_r6K}y3sE`T(6nJ*=yrs4YtcXjz}E55KTzF#s26HVr-H8%2bnW zlj~xhdess+iv(Wsbvmb)Q#rgYfE%;WEa82uC9)LOyiR^+;_k#3`2;6pMWUGvE5;U- zM4mMn4yf6-pgF*~O|Ch>wN22{EQOesVOhMmcv|* zR+4!Y%%rnjm1A9@HA$56~fykdQHEA7)Fw%ig?Oq3B4TEql>@%@b zHgJ4=T?&ep1d0~EZ=g=;K%B>&be0^WOga!7T|5^C+-{;78l4*@2CS7uE&|6vZ8$NJ zB(T0MD^apc{)Xrx126f}X(WnATMp^k@U}p4BASq{HKRb$+ML4ztW~2pidPsAD!R@X zFG9oseuN4c8#_E17dt!|sj;pkdP3|-=X|((TR8DQgKS zm8t+D^Qh$_RI75-yb@iW4Pc2naDu6PkwjI50SU~df!XH%-%g~cz+A>XJWYxDd{8LO zsDzPt+>EC$CU}{&n(7&eha9+m`cy^W#v!4UKkZ3lBAOeMJX@wvz?G@tuTI)q9Sy%& zOsnW8DThEgaxDT1h$a%i#*5|(WnNnrD2UGT`KOfTzp-roy^N8sKjl$ks*Ls{oSIhJ zwp&x>)F+*@pK*5O*pQKudc;AsgU%rcNb8;4PrtisH9rw5^9?grFmFa%PCgAL3ri>O zS{UeIiXNuyT3FrE6ij`_%v>mQPIpt?oOKDCf*o3*+{2WnY94~Z+T1zZPl#`G~GBLt5NLERZEY?D6wpGF}Jya*$RjM9>wiQx%l7 zIl{{EjO8KLsVt?Qjjq;eP-g*Yy7>#JVFrpyZH#k;DDS9;-vBmCWn}_nrZ4oO=gWVXUi?UE#A9rZ<5+pj^?Y?{wP<)t zG3M!1{=#&UdQ^=0h5Ur!nNynolV$UJwJOzLqIg$}hEM5?KJJP*c~|gCQc`O03y_qg zZi~R$?Ya;R&}Yp&w#E7E0AO+C%S@Pks`LR0!1`_Yvvk;V2thv2&^({2bxbl)W1?lC zioN4JwnXj!x6=$MF};IdFH?UI#H?l~d0M~4?Ah~YzioUwA{PD4CPT06*&-QMF`w4X z!Ig)!f8cytaXuf7*r1M?YQ;=lY>o!vr&gPz)uee(UQAWpy-!)5szwzl=BMIGN{<-O z+Jve4u3`gP90$pi7G|myAN9CcsGo_rr=tbMXj#$X3r3d{dVF3LejzUpE4urVAo;Q` zUkS{giBJ1gm4yK<`~lrzJByc#K$f#J%{TI}g}&k_N1Vzr;UcWckzM-2T%ev>)Ex zt!O7=kZ#(u>p*+=kweHKBY(UuIC7HaOixxjA$k;fIQ7Q!7|vKsNx}YD<~yk@XLi4n z=g+#J{g4YXLXMo5S=+>4f4Y+LBJhM=T!bo=H87TRzI_|Vvd;DG`)PJrYv07QvUmUe z#bQ^rsaP!{vf}NJc#|F+h}8VmW)%;FpIyqve&sp41qlGgrK!Wdw^|hPwI68T)rkQ{ zc`<_*xUchxgf1F>YbN)Gsa`@&I?`9dyCuAH+2kc6hd8W?44-_pGT|zZ&e5E3HTksE zRf9Dtvt*BtM^xmlIGTWBmD3{!9Qw-CDT-!LHth;FEEa$?mPfM|7W`$Mm{N3}cjPdf z>V(6bSZ$xub9)t|Uj4YgOHnF%wrPP01txWPZgb zQ~j!m9`&PIdHB!{a(e`!#&*y>wjnKEf9i=Ln%fUKirc1@8_&>w~{c_myRV;};^tGt1A#dcF~g*)ea6H@#2< zP+)!$;y2~rLJn}NLi6ut6TTusR1W_$5L^1c&96g0?7(%#Q8s-Xts0#tzDt zBNZcz2bmoavFeap0{hR-Pj!l4OIZVYsVB8CvyQ=CKj%;<;VjCovrP7$IGO!p{)V0$ zidVn3QtP≈>k0IHmWUD;@~8 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¬ULKzPOAG}Qf7EjDF* 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 z zu~~OPw^-`Jo|fH=&$QDVtJ`^NB3DQ@s6ww?FdsG;hF5EfT-xv(LoE zv&1;5B0Lut&lC9cLWX#eAO0yryu=?pmq85GD}+zw5IzMMC0_wKwa6f+7K=AnqBj}b zTg((c$_D80AH4lDF5c$fcjDr@Ea3D0#RmbL>PFyHH}O76d=M8O##LbVxWsBHV{>C| zL(7B>fHVz?gmtW4segnW+b<}@Ne3ZoAL7K{eF<^$MbM7LWlCJ8wg+(v1-$*g#y$Cw zMR2KqfpJif%v5OSP_2HJ{gYbr*Vmm=E2bo+m0)F7~sXg9VQF)YeShhg`q3Z zq8H7=S%!moTWiS-naNi`G#w}K?Qx=pw_|uic-!L``u8}|Vu__`pvg2 z%#qKsfk{E&(oS)f1-Hg>`}-hpDGfj`IogtAfbWV9S!|=1kW(gZ5MUNoIzO=FBstlV zQ&{&m;7mkEf;0O{{sjdvB{<7Fid_mvK7El9O`T0BT4x|k5-rxY7af^a`w>Sl8y!I$ z;b-k5j`$-qqR$+0l&#~0me$nPZBPi1AV(vr4VO{LI51~XNC}hN1;;B|8rQ5s){-uE zq<;;eS;Ccv`lWeqez`2+m&@?Weo+g{FQGmE&QPu?2;~}BRoDO-;8{L7pr!-p!cT~~ z=@?9A5jG`KkoLX|$QC*Xe8h>LQKRv?H|FOmfp}LrbcbaiDGzm zW&!MMgJROKiMa;vNPru1B#;1#iMdqNmKz+osle-G;+LdkgJLu#aykSwDZ~ne*$JhY z5~R5jG!YX6?w)X(hpGgwq{*#O(o6uwV1d~x4BCc8*1{eN!iVAY;U2;{rr31Ea!*nV z%YCy@VH0Ss2TjBugTpLb*rSyrpTbt6wnAx|Fu1Oq4WNmrW7tg&r^!T&5*#%srW(He zO?baT)I@QJ2UWZS98Lg-uSRgFh37bo1Jh-Pmcamf+%lXF4rhSFnGqZq$2g2bLlg%C z>~T3<2o4v4!_Ei}jcPYOQA@{0aWKFhm&4WIa1A(I8^NIo(50|4v_x?*z#f;wP2g}d zID9{X!xqFoNaTQ-Jw9bU91c$0DbEKM#xk)M2i^T%59Mr!vUWVMXJHXy2zopuw~Ji2 zeQH_{W5@aD9$M)Rt#sgb2#p~v!T_m-5@^9VZxEL?gxurUvi`k?T&6=V6I=aE2OZ-o z#*nLr(o#XTSDWYxh)g#+al7k4pZSc}sq`9CdR4pUh}4maI31mE^uH(0?z7M8J^Wq{ zn_fohRA~Qrg#zdVbOu=y7o+|8EQy2n0Bb)khHXac<|S}@*;5$Ha3L;+w5c1ckxXH3 zMA7KQ7>59y$#5}ncUp+5*_SYwehv(VT-8=RPMgQE*PDaztNDP#3;-NvIL=`g0TRRV z+VB@zP}amar{v?5r-I&#-panl@GLP{>risGG;HMSAeN^Z2p5hnq!g0)$crtR{i_R8XH5K|S0gVs{~w`p^*SrJz1P zf_k_)#H!v<_W)mpDGbJN1AK8Tt}F-eWjR=^@UXBg6@f2$4!}`^2my|(I*273r8g{v zr5&UstUc6g6+s*LV$Y?pL1H?hFJz@<2Ll_yW~XhmvL&(-z?1cmuL^*SYLATGdCHlX z^D#m?p9J(va+ASu=?D_VRYpCW+6}-aG0|JpKX9M*^bHbqP+SIOxra9pBH%Jr( z=}>?a3kbFGg?R{BsSzgHKq~N{+zy1v@hH#^1dBTXVGzC3j{Z)+>hIxqzNyip4Zl8$ z-$cc3B5f78O;X$@x*brEgkz3Qx{vO0r-U5q^|LhkdEZiQPV{T zsjAIoB#9d%NdyajkyH3cVz)*T(?!CDmeHRVvoKX*7N)zHg=wb2t4Rs)FKO~_=ZrPW*fR&&qk%iR(dyylHxTT% zj!a}x(fg?9rTT5 z)!$u@S5%rE3kG3uxebUwcdRCyY4f71Pp&PLc-4(W>D`UZwy2yt4UStDXs6sZ# z*I=n$$1wa?H2S}xbH4$Z-vY?#?_#k0rx+^V7Ng}mVyyg^(xaXgjZ>pPkqvzTKH=nx za{~q;C$b@5&0+N101ZS(b-5Yi{P&4$xB(~;T>>w%VS$TmSg4T=lu#oZG$bYykeKXP zmZvtmsM(iBHs~3pqb(pCZUHasp&DLZWP_KNMmFTR$Of|2$cCOkHuM6rp*Ps}1+t+Z zkPZETZ19fxeH;<;&Ge8W*vN)kh-|nOAH>9Meq_V&tE&2~93lj-k@!K>29!DB%*;~( zXv2~$j39Sq5Ua3M+|3)X3QNU)-tHmz0BD7!L@O*MT4AYpfH#DCSxV5tQigh2%1|#$ z8R{jEp!5@6wa#g-6Ac`~>I) zgn7xr>=~GaXNXl;%J44F5UB7BW4t^=sKPT0^zsbB3QNVyh!d3sFb8lJOU0{k;uQ+T zYZ-(rj1Ygx5P#+82=?-*c!Re$GfbS9r7F%#2BW;ZBmOsw5rp_lz!a7erm$4O6sQtp zo?i;T4&uCsx#F&D277_Cnt#*c;s>C~?DLN@-b)^{&*w4w{8E_($46X6dx^uLkvwQi zYI9Q+&<~#vu%V+FjSnEHYxn0z!k89F#jc@93 z3{W4Rv%gR$lI;!aB@LUm@Wf+vWxaxw#A+MBNI!u6Z12}NuB_dPOk3Psxy^j3a)X*@ zvEkoKISRsl0(X=-rwGEUsw+1j!^ zug39)04`(Y1l}fE*f==T5+{pOl7JO15<6i_)EME(;mHj_e4bXUVCL)7&leQZ5ROdf zD6Zj)j9}=1*Yq=utrC{ZcUd&(%42rg$2xFb^=|JL>ODM(1f>L}sQBpo;Zruc& z)+fhcd_sW5=MdC{=!_I%{E#V;2h14WggZKzz^K0(;y}Lw_ZFoJaY82sw?1=KV%fYH zPN$CI-2@~#1Yc>lqZ`_!3qsDW#pimfGuP}ZktjD}88;;X$zgyDq^6z2ORx!vL&w++ zAtf8hK^GPV9yiBOsb$l%gk1DXeeCL^|l(L4(KUYaIdx}=$aT~G&g}}4TP=r(9CjZX2DaSL#C_--Xa#R0E1C* z|hMqzZ{(CSX1Fm7}kX0 zO;UZmUiZ_zXexIhG21>5BfH1rai^bRU13Q3up7btq%j2#po2f?A(-v7`)sE#VS!}` zdi*9%JQ8X`)A}Vm3%~NvN_S|bJADYtHbcvY-EhO3xa6KfdH>)crx6?A24!pe5#z$n zkUJhqOvQJD0^v>ay0wY!N~?MK>XpZuDz}Sx4$nOg5XTFm2ZEanMA`$|EbX!w

3$ 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 literal 0 HcmV?d00001 diff --git a/trunk/libsrc/LZMA/build.xml b/trunk/libsrc/LZMA/build.xml index 9228eac00..39c801a28 100644 --- a/trunk/libsrc/LZMA/build.xml +++ b/trunk/libsrc/LZMA/build.xml @@ -51,8 +51,7 @@ -init-macrodef-junit: defines macro for junit execution -init-macrodef-debug: defines macro for class debugging -init-macrodef-java: defines macro for class execution - -do-jar-with-manifest: JAR building (if you are using a manifest) - -do-jar-without-manifest: JAR building (if you are not using a manifest) + -do-jar: JAR building run: execution of project -javadoc-build: Javadoc generation test-report: JUnit report generation diff --git a/trunk/libsrc/LZMA/nbproject/build-impl.xml b/trunk/libsrc/LZMA/nbproject/build-impl.xml index 8e7313383..4144cb57a 100644 --- a/trunk/libsrc/LZMA/nbproject/build-impl.xml +++ b/trunk/libsrc/LZMA/nbproject/build-impl.xml @@ -54,6 +54,7 @@ is divided into following sections: + @@ -71,10 +72,11 @@ is divided into following sections: - + - - + + + @@ -91,12 +93,6 @@ is divided into following sections: - - - - - - @@ -115,24 +111,12 @@ is divided into following sections: - + - + - - - - - - - - - - - - @@ -186,7 +170,15 @@ is divided into following sections: - + + + + + + + + + @@ -275,6 +267,7 @@ is divided into following sections: + @@ -314,6 +307,7 @@ is divided into following sections: + @@ -446,7 +440,7 @@ is divided into following sections: - + @@ -837,8 +831,8 @@ is divided into following sections: - - + + @@ -850,7 +844,7 @@ is divided into following sections: - + @@ -966,41 +960,25 @@ is divided into following sections: - - - - - - - - - - - - - To run this application from the command line without Ant, try: - - - - - - - java -cp "${run.classpath.with.dist.jar}" ${main.class} - - + - + - + - + + + + + + @@ -1008,23 +986,41 @@ is divided into following sections: - + To run this application from the command line without Ant, try: java -jar "${dist.jar.resolved}" - + + + + + + + + + + + + + + + + + - + + - + + + + + + + + + + + Builds, tests, and runs the project ttf. + + + diff --git a/trunk/libsrc/ttf/manifest.mf b/trunk/libsrc/ttf/manifest.mf new file mode 100644 index 000000000..1574df4a2 --- /dev/null +++ b/trunk/libsrc/ttf/manifest.mf @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +X-COMMENT: Main-Class will be added automatically by build + diff --git a/trunk/libsrc/ttf/nbproject/build-impl.xml b/trunk/libsrc/ttf/nbproject/build-impl.xml new file mode 100644 index 000000000..2451f7f11 --- /dev/null +++ b/trunk/libsrc/ttf/nbproject/build-impl.xml @@ -0,0 +1,1407 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + No tests executed. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + Must select one file in the IDE or set profile.class + This target only works when run from inside the NetBeans IDE. + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + + + Must select some files in the IDE or set test.includes + + + + + Must select one file in the IDE or set run.class + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + Must select some files in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + Must select one file in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + + + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/trunk/libsrc/ttf/nbproject/genfiles.properties b/trunk/libsrc/ttf/nbproject/genfiles.properties new file mode 100644 index 000000000..115ce4b20 --- /dev/null +++ b/trunk/libsrc/ttf/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=ffc041f7 +build.xml.script.CRC32=9bce9219 +build.xml.stylesheet.CRC32=8064a381@1.68.1.46 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=ffc041f7 +nbproject/build-impl.xml.script.CRC32=b06e210e +nbproject/build-impl.xml.stylesheet.CRC32=5a01deb7@1.68.1.46 diff --git a/trunk/libsrc/ttf/nbproject/project.properties b/trunk/libsrc/ttf/nbproject/project.properties new file mode 100644 index 000000000..10ccdfd83 --- /dev/null +++ b/trunk/libsrc/ttf/nbproject/project.properties @@ -0,0 +1,75 @@ +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.processors.list= +annotation.processing.run.all.processors=true +annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output +application.title=ttf +application.vendor=Jindra +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# Files in build.classes.dir which should be excluded from distribution jar +dist.archive.excludes= +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=../../lib/ttf.jar +dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= +excludes= +includes=** +jar.compress=false +javac.classpath= +# Space-separated list of extra javac options +javac.compilerargs=-Xlint:unchecked -Xlint:deprecation +javac.deprecation=false +javac.processorpath=\ + ${javac.classpath} +javac.source=1.7 +javac.target=1.7 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +javac.test.processorpath=\ + ${javac.test.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +main.class=fontatest.FontaTest +manifest.file=manifest.mf +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=default_platform +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project. +# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. +# To set system properties for unit tests define test-sys-prop.name=value: +run.jvmargs= +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.dir=src +test.src.dir=test diff --git a/trunk/libsrc/ttf/nbproject/project.xml b/trunk/libsrc/ttf/nbproject/project.xml new file mode 100644 index 000000000..bce7aa78c --- /dev/null +++ b/trunk/libsrc/ttf/nbproject/project.xml @@ -0,0 +1,15 @@ + + + org.netbeans.modules.java.j2seproject + + + ttf + + + + + + + + + diff --git a/trunk/libsrc/ttf/src/fontastic/FContour.java b/trunk/libsrc/ttf/src/fontastic/FContour.java new file mode 100644 index 000000000..63f44d05a --- /dev/null +++ b/trunk/libsrc/ttf/src/fontastic/FContour.java @@ -0,0 +1,86 @@ +package fontastic; + +/** + * Fontastic + * A font file writer to create TTF and WOFF (Webfonts). + * http://code.andreaskoller.com/libraries/fontastic + * + * Copyright (C) 2013 Andreas Koller http://andreaskoller.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * @author Andreas Koller http://andreaskoller.com + * @modified 06/19/2013 + * @version 0.4 (4) + */ + +import fontastic.FPoint; + +import java.util.ArrayList; +import java.util.List; + +/** + * Class FContour + * + * Stores a contour (list of FPoint). + * + */ +public class FContour { + + List points; + + FContour() { + this.points = new ArrayList<>(); + } + + FContour(PVector[] points) { + this.points = new ArrayList<>(); + for (PVector p : points) { + this.points.add(new FPoint(p)); + } + } + + FContour(PVector[] points, PVector[] controlpoints) { + this.points = new ArrayList<>(); + for (int i=0; i(); + for (int i=0; i getPoints() { + return points; + } + + public FPoint[] getPointsArray() { + FPoint[] pointsArray = points.toArray(new FPoint[points.size()]); + return pointsArray; + } + + public void setPoints(PVector[] points) { + this.points = new ArrayList<>(); + for (PVector p : points) { + this.points.add(new FPoint(p)); + } + } + +} \ No newline at end of file diff --git a/trunk/libsrc/ttf/src/fontastic/FGlyph.java b/trunk/libsrc/ttf/src/fontastic/FGlyph.java new file mode 100644 index 000000000..b2b0a53c7 --- /dev/null +++ b/trunk/libsrc/ttf/src/fontastic/FGlyph.java @@ -0,0 +1,116 @@ +package fontastic; + +/** + * Fontastic + * A font file writer to create TTF and WOFF (Webfonts). + * http://code.andreaskoller.com/libraries/fontastic + * + * Copyright (C) 2013 Andreas Koller http://andreaskoller.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * @author Andreas Koller http://andreaskoller.com + * @modified 06/19/2013 + * @version 0.4 (4) + */ + + +import java.util.ArrayList; +import java.util.List; + +/** + * Class FGlyph + * + * Stores a glyph with all its properties. + * + */ +public class FGlyph { + + private char glyphChar; + private List contours; + private int advanceWidth = 512; + + FGlyph(char c) { + glyphChar = c; + this.contours = new ArrayList<>(); + } + + public void addContour() { + contours.add(new FContour()); + } + + public void addContour(PVector[] points) { + contours.add(new FContour(points)); + } + + public void addContour(FPoint[] points) { + contours.add(new FContour(points)); + } + + public void addContour(PVector[] points, PVector[] controlPoints) { + contours.add(new FContour(points, controlPoints)); + } + + public void addContour(FContour contour) { + contours.add(contour); + } + + public void setAdvanceWidth(int advanceWidth) { + this.advanceWidth = advanceWidth; + } + + public char getGlyphChar() { + return glyphChar; + } + + public int getAdvanceWidth() { + return advanceWidth; + } + + public List getContours() { + return contours; + } + + public FContour[] getContoursArray() { + FContour[] contoursArray = contours.toArray(new FContour[contours.size()]); + return contoursArray; + } + + public FContour getContour(int index) { + return contours.get(index); + } + + public int getContourCount() { + return contours.size(); + } + + public void setContour(int index, PVector[] points) { + contours.set(index, new FContour(points)); + } + + public void setContour(int index, FPoint[] points) { + contours.set(index, new FContour(points)); + } + + public void setContour(int index, FContour contour) { + contours.set(index, contour); + } + + public void clearContours() { + this.contours.clear(); + } + +} \ No newline at end of file diff --git a/trunk/libsrc/ttf/src/fontastic/FPoint.java b/trunk/libsrc/ttf/src/fontastic/FPoint.java new file mode 100644 index 000000000..e2bd71bcb --- /dev/null +++ b/trunk/libsrc/ttf/src/fontastic/FPoint.java @@ -0,0 +1,82 @@ +package fontastic; + +/** + * Fontastic + * A font file writer to create TTF and WOFF (Webfonts). + * http://code.andreaskoller.com/libraries/fontastic + * + * Copyright (C) 2013 Andreas Koller http://andreaskoller.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * @author Andreas Koller http://andreaskoller.com + * @modified 06/19/2013 + * @version 0.4 (4) + */ + + + +/** + * Class FPoint extends PVector + * + * Stores a point with x and y coordinates and optional PVector controlPoint1 and controlPoint2. + * + */ +public class FPoint extends PVector { + + public PVector controlPoint; + + private boolean hasControlPoint; + + public FPoint() { + } + + public FPoint(PVector point) { + this.x = point.x; + this.y = point.y; + this.hasControlPoint = false; + } + + public FPoint(float x, float y) { + this.x = x; + this.y = y; + this.hasControlPoint = false; + } + + + public FPoint(PVector point, PVector controlPoint) { + this.x = point.x; + this.y = point.y; + this.controlPoint = controlPoint; + this.hasControlPoint = true; + } + + public void setControlPoint(PVector controlPoint1) { + this.controlPoint = controlPoint1; + this.hasControlPoint = true; + } + + public void setControlPoint(float x, float y) { + this.controlPoint = new PVector(x,y); + this.hasControlPoint = true; + } + + + public boolean hasControlPoint1() { + return hasControlPoint; + } + +} \ No newline at end of file diff --git a/trunk/libsrc/ttf/src/fontastic/Fontastic.java b/trunk/libsrc/ttf/src/fontastic/Fontastic.java new file mode 100644 index 000000000..717939e92 --- /dev/null +++ b/trunk/libsrc/ttf/src/fontastic/Fontastic.java @@ -0,0 +1,518 @@ +/** + * Fontastic A font file writer to create TTF + * http://code.andreaskoller.com/libraries/fontastic + * + * Copyright (C) 2013 Andreas Koller http://andreaskoller.com + * + * Uses: doubletype http://sourceforge.net/projects/doubletype/ for TTF creation + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * @author Andreas Koller http://andreaskoller.com + * @modified 03/16/2014 JPEXS - removed Woff + * @version 0.4 (4) + */ +package fontastic; + +import org.doubletype.ossa.*; +import org.doubletype.ossa.module.*; +import org.doubletype.ossa.adapter.*; + +import java.io.*; +import java.util.ArrayList; +import java.util.Map; +import java.util.List; +import java.util.Scanner; +import java.util.regex.Pattern; +import java.util.regex.Matcher; + +/** + * Fontastic A font file writer to create TTF and WOFF (Webfonts). + * http://code.andreaskoller.com/libraries/fontastic + * + */ +public class Fontastic { + + private org.doubletype.ossa.module.TypefaceFile typeface; + private org.doubletype.ossa.Engine m_engine; + + private String fontname; + + private List glyphs; + + private int advanceWidth = 512; + + private File ttffile; + private File outfile; + private File tempDir; + + public final static String VERSION = "0.4"; + + /** + * Uppercase alphabet 26 characters * + */ + public final static char alphabet[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', + 'U', 'V', 'W', 'X', 'Y', 'Z'}; + /** + * Lowercase alphabet 26 characters * + */ + public final static char alphabetLc[] = {'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', + 't', 'u', 'v', 'w', 'x', 'y', 'z'}; + + /** + * Return the version of the library. + * + * @return String + */ + public static String version() { + return VERSION; + } + + /** + * Constructor + * + * @example Fontastic f = new Fontastic(this, "MyFont"); + * + * @param theParent Your processing sketch (this). + * @param fontname Font name + * + */ + public Fontastic(String fontname, File outfile) throws IOException { + this.fontname = fontname; + this.outfile = outfile; + intitialiseFont(); + this.glyphs = new ArrayList<>(); + } + + /** + * Returns the font name. + * + * @return String + */ + public String getFontname() { + return fontname; + } + + private static File createTempDirectory() + throws IOException { + File temp; + temp = File.createTempFile("temp", Long.toString(System.nanoTime())); + + + + if (!(temp.delete())) { + throw new IOException("Could not delete temp file: " + temp.getAbsolutePath()); + } + + if (!(temp.mkdirs())) { + throw new IOException("Could not create temp directory: " + temp.getAbsolutePath()); + } + + return (temp); + } + + /** + * Creates and initialises a new typeface. Font data is put into sketch + * folder data/fontname. + */ + private void intitialiseFont() throws IOException { + + tempDir = createTempDirectory(); + /*if (!tempDir.exists()) { + if(!tempDir.mkdirs()){ + if (!tempDir.exists()) { + throw new IOException("Cannot create temp dir"); + } + } + } else { + //deleteFolderContents(tempDir, false); + }*/ + + + m_engine = Engine.getSingletonInstance(); + m_engine.buildNewTypeface(fontname, tempDir); + + this.setFontFamilyName(fontname); + this.setVersion("CC BY-SA 3.0 http://creativecommons.org/licenses/by-sa/3.0/"); // default + // license + + String directoryName = tempDir + File.separator + "bin" + File.separator; + + ttffile = new File(directoryName + fontname + ".ttf"); + } + + /** + * Builds the font and writes the .ttf and the .woff file as well as a HTML + * template for previewing the WOFF. If debug is set (default is true) then + * you'll see the .ttf and .woff file name in the console. + */ + public void buildFont() throws FileNotFoundException { + // Create TTF file with doubletype + m_engine.getTypeface().addRequiredGlyphs(); + //m_engine.fireAction(); + //m_engine.addDefaultGlyphs(); + + for (FGlyph glyph : glyphs) { + + m_engine.checkUnicodeBlock(glyph.getGlyphChar()); + GlyphFile glyphFile = m_engine.addNewGlyph(glyph.getGlyphChar()); + glyphFile.setAdvanceWidth(glyph.getAdvanceWidth()); + + for (FContour contour : glyph.getContours()) { + + EContour econtour = new EContour(); + econtour.setType(EContour.k_quadratic); + + for (FPoint point : contour.points) { + + EContourPoint e = new EContourPoint(point.x, point.y, true); + if (point.hasControlPoint1()) { + + econtour.addContourPoint(new EContourPoint(point.controlPoint.x, point.controlPoint.y, false)); + /*EControlPoint cp1 = new EControlPoint(true, + point.controlPoint1.x, point.controlPoint1.y); + e.setControlPoint1(cp1); + */ + } +/* + if (point.hasControlPoint2()) { + EControlPoint cp2 = new EControlPoint(false, + point.controlPoint2.x, point.controlPoint2.y); + e.setControlPoint2(cp2); + } */ + + econtour.addContourPoint(e); + } + + glyphFile.addContour(econtour); + } + glyphFile.saveGlyphFile(); + } + + m_engine.buildTrueType(false); + + // End TTF creation + if(outfile.exists()){ + outfile.delete(); + } + ttffile.renameTo(outfile); + cleanup(); + } + + /** + * Deletes all the glyph files created by doubletype in your data/fontname + * folder. + */ + private void cleanup() { + File[] filesToExclude = new File[0]; + + deleteFolderContents(tempDir, true, filesToExclude); + + } + + /** + * Sets the author of the font. + */ + public void setAuthor(String author) throws FileNotFoundException { + m_engine.setAuthor(author); + } + + /** + * Sets the copyright year of the font. + */ + public void setCopyrightYear(String copyrightYear) throws FileNotFoundException { + m_engine.setCopyrightYear(copyrightYear); + } + + /** + * Sets the version of the font (default is "0.1"). + */ + public void setVersion(String version) { + m_engine.getTypeface().getGlyph().getHead().setVersion(version); + } + + /** + * Sets the font family name of the font. Also called in the constructor. If + * changed with setFontFamilyName() it won't affect folder the font is + * stored in. + */ + public void setFontFamilyName(String fontFamilyName) throws FileNotFoundException { + m_engine.setFontFamilyName(fontFamilyName); + } + + /** + * Sets the sub family of the font. + */ + public void setSubFamily(String subFamily) throws FileNotFoundException { + m_engine.getTypeface().setSubFamily(subFamily); + } + + /** + * Sets the license of the font (default is "CC BY-SA 3.0 + * http://creativecommons.org/licenses/by-sa/3.0/") + */ + public void setTypefaceLicense(String typefaceLicense) throws FileNotFoundException { + m_engine.setTypefaceLicense(typefaceLicense); + } + + /** + * Sets the baseline of the font. + */ + public void setBaseline(float baseline) throws FileNotFoundException { + m_engine.setBaseline(baseline); + } + + /** + * Sets the meanline of the font. + */ + public void setMeanline(float meanline) throws FileNotFoundException { + m_engine.setMeanline(meanline); + } + + /** + * Sets the advanceWidth of the font. Can be changed for every glyph + * individually. Won't affect already created glyphs. + */ + public void setAdvanceWidth(int advanceWidth) { + m_engine.setAdvanceWidth(advanceWidth); + this.advanceWidth = advanceWidth; + } + + public void setTopSideBearing(float topSideBearing) throws FileNotFoundException { + try { + m_engine.getTypeface().setTopSideBearing(topSideBearing); + } catch (OutOfRangeException e) { + System.out + .println("Error while setting aopSideBearing (must be within range " + + m_engine.getTypeface().getEm()); + e.printStackTrace(); + } + } + + public void setBottomSideBearing(float bottomSideBearing) throws FileNotFoundException { + try { + m_engine.getTypeface().setBottomSideBearing(bottomSideBearing); + } catch (OutOfRangeException e) { + System.out + .println("Error while setting bottomSideBearing (must be within range " + + m_engine.getTypeface().getEm()); + e.printStackTrace(); + } + } + + public void setAscender(float ascender) throws FileNotFoundException { + try { + m_engine.getTypeface().setAscender(ascender); + } catch (OutOfRangeException e) { + System.out + .println("Error while setting ascender (must be within range 0 to " + + m_engine.getTypeface().getEm() + ")"); + e.printStackTrace(); + } + } + + public void setDescender(float descender) throws FileNotFoundException { + try { + m_engine.getTypeface().setDescender(descender); + } catch (OutOfRangeException e) { + System.out + .println("Error while setting descender (must be within range 0 to " + + m_engine.getTypeface().getEm() + ")"); + e.printStackTrace(); + } + } + + public void setXHeight(float xHeight) throws FileNotFoundException { + try { + m_engine.getTypeface().setXHeight(xHeight); + } catch (OutOfRangeException e) { + System.out + .println("Error while setting xHeight (must be within range 0 to " + + m_engine.getTypeface().getEm() + + " as well as lower than the ascender " + + m_engine.getTypeface().getAscender() + ")"); + e.printStackTrace(); + } + } + + /** + * Sets the default metrics for the typeface: setTopSideBearing(170); // 2 + * px setAscender(683); // 8 px setXHeight(424); // 5 px setDescender(171); + * // 2 px setBottomSideBearing(0); // 0px + * + */ + public void setDefaultMetrics() throws FileNotFoundException { + m_engine.getTypeface().setDefaultMetrics(); + } + + /** + * Add a glyph + * + * @param c Character of the glyph. + * + * @return FGlyph that has been created. + * + */ + public FGlyph addGlyph(char c) { + + FGlyph glyph = new FGlyph(c); + glyph.setAdvanceWidth(advanceWidth); + glyphs.add(glyph); + return glyph; + + } + + /** + * Add a glyph and its one contour + * + * @param c Character of the glyph. + * + * @param FContour Shape of the glyph as FContour. + * + * @return The glyph FGlyph that has been created. You can use this to store + * the glyph and add contours afterwards. Alternatively, you can call + * getGlyph(char c) to retrieve it. + */ + public FGlyph addGlyph(char c, FContour contour) { + + FGlyph glyph = new FGlyph(c); + glyphs.add(glyph); + glyph.addContour(contour); + + glyph.setAdvanceWidth(advanceWidth); + return glyph; + + } + + /** + * Add a glyph and its contours + * + * @param c Character of the glyph. + * + * @param FContour [] Shape of the glyph in an array of FContour. + * + * @return The FGlyph that has been created. You can use this to store the + * glyph and add contours afterwards. Alternatively, you can call + * getGlyph(char c) to retrieve it. + */ + public FGlyph addGlyph(char c, FContour[] contours) { + + FGlyph glyph = new FGlyph(c); + glyphs.add(glyph); + + for (FContour contour : contours) { + // if (debug) System.out.println(p.x + " - " + p.y); + glyph.addContour(contour); + } + glyph.setAdvanceWidth(advanceWidth); + return glyph; + + } + + /** + * Get glyph by character + * + * @param c The character of the glyph + * + * @return The glyph + */ + public FGlyph getGlyph(char c) { + + FGlyph glyph = null; + for (int i = 0; i < glyphs.size(); i++) { + if (glyphs.get(i).getGlyphChar() == c) { + glyph = glyphs.get(i); + break; + } + } + return glyph; + + } + + /** + * Engine getter + * + * @return The doubletype Engine used for font creation, so that you can + * access all functions of doubletype in case you need them. + */ + public Engine getEngine() { + return m_engine; + } + + /** + * Returns the TypefaceFile + * + * @return The doubletype TypefaceFile used for font creation, so that you + * can access functions of doubletype in case you need them. + */ + public TypefaceFile getTypefaceFile() { + return m_engine.getTypeface(); + } + + /** + * Returns the .ttf file name + * + * @return The .ttf file name, which is being created when you call build() + */ + public String getTTFfilename() { + return ttffile.toString(); + } + + private static void deleteFolderContents(File folder, + boolean deleteFolderItself) { + File[] files = folder.listFiles(); + if (files != null) { // some JVMs return null for empty dirs + for (File f : files) { + if (f.isDirectory()) { + deleteFolderContents(f, true); + f.delete(); + } else { + f.delete(); + } + } + } + if (deleteFolderItself) { + folder.delete(); + } + } + + private static void deleteFolderContents(File folder, + boolean deleteFolderItself, File[] exceptions) { + File[] files = folder.listFiles(); + if (files != null) { // some JVMs return null for empty dirs + for (File f : files) { + boolean deleteFile = true; + for (File exceptfile : exceptions) { + if (f.equals(exceptfile)) { + deleteFile = false; + } + } + if (deleteFile) { + if (f.isDirectory()) { + deleteFolderContents(f, true, exceptions); + f.delete(); + } else { + f.delete(); + } + } + } + } + if (deleteFolderItself) { + folder.delete(); + } + } +} diff --git a/trunk/libsrc/ttf/src/fontastic/PVector.java b/trunk/libsrc/ttf/src/fontastic/PVector.java new file mode 100644 index 000000000..42786aab2 --- /dev/null +++ b/trunk/libsrc/ttf/src/fontastic/PVector.java @@ -0,0 +1,27 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package fontastic; + +/** + * + * @author JPEXS + */ +public class PVector { + public double x; + public double y; + + public PVector() { + } + + + + public PVector(double x, double y) { + this.x = x; + this.y = y; + } + +} diff --git a/trunk/libsrc/ttf/src/fontatest/FontaTest.java b/trunk/libsrc/ttf/src/fontatest/FontaTest.java new file mode 100644 index 000000000..801ba5211 --- /dev/null +++ b/trunk/libsrc/ttf/src/fontatest/FontaTest.java @@ -0,0 +1,31 @@ +package fontatest; + +import fontastic.FPoint; +import fontastic.Fontastic; +import fontastic.PVector; +import java.io.File; +import java.io.IOException; + + +public class FontaTest { + + /** + * @param args the command line arguments + */ + public static void main(String[] args) throws IOException { + File file=new File("example.ttf"); + file.delete(); + Fontastic f = new Fontastic("ExampleFont",file); + f.setAuthor("Nobody"); + FPoint[] points = new FPoint[]{ // Define a PVector array containing the points of the shape + new FPoint(0, 0), + new FPoint(512,0), + //new FPoint(256, 1024), + new FPoint(new PVector(256,1024), new PVector(512,512)), + new FPoint(0, 0) + }; + f.addGlyph('P').addContour(points); // Assign contour to character A + f.buildFont(); + } + +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/ActiveList.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/ActiveList.java new file mode 100644 index 000000000..dfacfb5fa --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/ActiveList.java @@ -0,0 +1,199 @@ + /* + * $Id: ActiveList.java,v 1.7 2004/11/15 03:39:38 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa; + +import java.util.*; + +import org.doubletype.ossa.adapter.*; + +/** + * @author e.e + */ +public class ActiveList { + private static ActiveList s_actives = null; + + public static ActiveList getSingletonInstance() { + if (s_actives == null) + s_actives = new ActiveList(); + + return s_actives; + } + + // -------------------------------------------------------------- + + public ArrayList m_activeObjects = new ArrayList<>(); + + public void unselectAll() { + m_activeObjects.clear(); + } + + public boolean hasSelected() { + return size() > 0; + } + + public int size() { + return m_activeObjects.size(); + } + + public GlyphObject get(int a_index) { + return m_activeObjects.get(a_index); + } + + public boolean isSelected(Object a_value) { + int i; + + // use equal method to compare this will catch XContour etc... + for (i = 0; i < size(); i++) { + if (get(i) == a_value) { + return true; + } // if + } // for i + + return false; + } + + public void addActive(GlyphObject a_object) { + if (isSelected(a_object)) { + return; + } // if + + m_activeObjects.add(a_object); + } + + public void setActives(ActiveList a_actives) { + unselectAll(); + + int i; + for (i = 0; i < a_actives.size(); i++) { + addActive(a_actives.get(i)); + } // for i + } + + private GlyphObject getTheActive() { + GlyphObject retval = null; + + if (m_activeObjects.size() == 1) { + retval = get(0); + } // if + + return retval; + } + + public boolean hasActiveModule() { + return (getTheActive() instanceof EModuleInvoke); + } + + public EModuleInvoke getActiveModule() { + if (hasActiveModule()) { + return (EModuleInvoke) getTheActive(); + } else { + return null; + } // if-else + } + + public boolean hasActiveContour() { + return (getTheActive() instanceof EContour); + } + + public EContour getActiveContour() { + if (getTheActive() instanceof EContour) { + return (EContour) getTheActive(); + } else { + return null; + } // if-else + } + + public boolean hasActiveInclude() { + return (getTheActive() instanceof EIncludeInvoke); + } + + public EIncludeInvoke getActiveInclude() { + if (hasActiveInclude()) { + return (EIncludeInvoke) getTheActive(); + } // if + + return null; + } + + public boolean hasActiveControlPoint() { + return (getTheActive() instanceof EControlPoint); + } + + public EControlPoint getActiveControlPoint() { + if (hasActiveControlPoint()) { + return (EControlPoint) getTheActive(); + } // if + + return null; + } + + public boolean hasActivePoint() { + return (getTheActive() instanceof EContourPoint); + } + + public EContourPoint getActivePoint() { + if (hasActivePoint()) { + return (EContourPoint) getTheActive(); + } else { + return null; + } // if + } + + public boolean hasActiveHint() { + return (getTheActive() instanceof EHint); + } + + public String getSelectedAsString() { + String retval = ""; + + if (!hasSelected()) { + return retval; + } // if + + retval = ""; + + int i; + for (i = 0; i < size(); i++) { + GlyphObject active = get(i); + retval += active.toString(); + } // for i + + retval += ""; + + return retval; + } + +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/AppSettings.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/AppSettings.java new file mode 100644 index 000000000..f5ca77e1e --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/AppSettings.java @@ -0,0 +1,55 @@ +/* + */ +package org.doubletype.ossa; + +import java.io.*; +import java.util.Properties; + +/** + * @author e.e + */ +public class AppSettings extends Object { + private static String k_lastTypefaceFile = "lastTypefaceFile"; + + private static File s_fileName = new File("./.properties"); + private static Properties s_properties; + + public static String getLastTypefaceDir() { + loadPropertyFile(); + return s_properties.getProperty(k_lastTypefaceFile, "./"); + } + + public static void setLastTypefaceDir(String a_value) { + loadPropertyFile(); + s_properties.setProperty(k_lastTypefaceFile, a_value); + savePropertyFile(); + } + + private static void loadPropertyFile() { + if (s_properties != null) { + return; + } // if + + s_properties = new Properties(); + if (s_fileName.exists()) { + try { + s_properties.load(new FileInputStream(s_fileName)); + } catch (IOException e) { + e.printStackTrace(); + } // try-catch + } // if + } + + private static void savePropertyFile() { + if (s_properties == null) { + return; + } // if + + try { + s_properties.store(new FileOutputStream(s_fileName), + "DoubleType AppSetting File"); + } catch (IOException e) { + e.printStackTrace(); + } // try-catch + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/Engine.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/Engine.java new file mode 100644 index 000000000..94c92bd19 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/Engine.java @@ -0,0 +1,762 @@ +/* + * $Id: Engine.java,v 1.84 2004/12/27 04:56:03 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa; + +import java.awt.*; +import java.awt.datatransfer.*; +import java.awt.event.*; +import java.awt.geom.*; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.*; +import java.io.*; +import java.net.MalformedURLException; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.*; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.*; +import javax.swing.event.*; + +import org.doubletype.ossa.adapter.*; +import org.doubletype.ossa.module.*; +import org.doubletype.ossa.truetype.*; + +/** + * @author e.e + */ +public class Engine { + // -------------------------------------------------------------- + + // used by findFile + public static final int USER_CANCELLED = -1; + public static final int FILE_NOT_FOUND = 0; + public static final int FILE_FOUND = 1; + + // used by Find + public static final int SEARCH_BY_EXAMPLE = 0; + public static final int SEARCH_UNICODE = 1; + public static final int SEARCH_JIS_CODE = 2; + + // public static final double k_fontSizes [] = {9, 10, 11, 12, 14, 18, 24, 36, 72}; + public static final int k_defaultPixelSize = 16; + public static final int k_resolutions [] = {96, 72, 75, 100}; + public static final int k_defaultResolution = 96; + public static final int k_zooms [] = {25, 50, 100}; + public static final int k_defaultZoom = 100; + + // -------------------------------------------------------------- + + private static int s_em = 1024; + private static Engine s_singleton = null; + + public static Engine getSingletonInstance() { + if (s_singleton == null) + s_singleton = new Engine(); + return s_singleton; + } + + public static int getEm() { + return TTPixelSize.getEm(); + } + + // -------------------------------------------------------------- + + private UiBridge m_ui; + + private TypefaceFile m_typeface; + private GlyphFile m_root; + private ActiveList m_actives; + private ArrayList m_listeners = new ArrayList<>(); + + private String m_foundFileName; + private Clipboard m_clipboard; + private JFileChooser m_gifChooser; + private JFileChooser m_chooser; + + private Action m_deleteAction; + private Action m_addPointAction; + private Action m_toggleAction; + private Action m_hintAction; + private Action m_contourAction; + private Action m_moduleAction; + private Action m_includeAction; + private Action m_selectNextAction; + private Action m_roundAction; + private Action m_propertyAction; + private Action m_convertControlPointAction; + private Action m_convertContourAction; + + private String m_msgAlreadyExists = " already exists!"; + private String m_msgNoTypeface = "no typeface"; + private String m_msgEmptyGlyphTitle = "glyph title is empty"; + private String m_msgGlyphName = "glyph name?"; + private String m_msgCircular = "circular include!"; + private String m_msgNoJis = "Charset ISO-2022-JP is not supported.\n" + + "Please include charsets.jar in classpath."; + + // -------------------------------------------------------------- + + private Engine() { + //GlyphFactory.setFactory(new EGlyphFactory()); + + + + m_typeface = null; + m_root = null; + + m_clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + m_actives = ActiveList.getSingletonInstance(); + + initActions(); + } + + private void initActions() { + + } + + public Action [] buildCommands() { + ArrayList actions = buildCommandsArrayList(); + Action [] retval = new Action[actions.size()]; + int i; + for (i = 0; i < actions.size(); i++) { + retval[i] = (Action) actions.get(i); + } // for i + + return retval; + } + + private ArrayList buildCommandsArrayList() { + ArrayList retval = new ArrayList<>(); + + if (m_root == null) { + return retval; + } // if + + if (m_actives.hasActiveContour()) { + retval.add(m_convertContourAction); + } + + if (m_actives.hasActiveControlPoint()) { + EControlPoint controlPoint = m_actives.getActiveControlPoint(); + retval.add(m_convertControlPointAction); + } + + if (m_actives.hasActivePoint()) { + EContourPoint point = m_actives.getActivePoint(); + + retval.add(m_toggleAction); + + if (!point.isRounded()) { + retval.add(m_hintAction); + } // if + + if (!point.hasHintForCurrentPpem()) { + retval.add(m_roundAction); + } // if + } // if + + if (m_actives.size() > 0) { + // retval.add(m_propertyAction); + retval.add(m_deleteAction); + } // if + + if (m_actives.hasActivePoint()) { + retval.add(m_addPointAction); + } // if + + /*if (!GlyphAction.isPointVisible()) { + retval.add(m_moduleAction); + retval.add(m_contourAction); + retval.add(m_includeAction); + } // if*/ + + return retval; + } + + public void localize(ResourceBundle a_bundle) { + m_msgAlreadyExists = a_bundle.getString("msgAlreadyExists"); + m_msgNoTypeface = a_bundle.getString("msgNoTypeface"); + m_msgEmptyGlyphTitle = a_bundle.getString("msgEmptyGlyphTitle"); + m_msgGlyphName = a_bundle.getString("msgGlyphName"); + m_msgCircular = a_bundle.getString("msgCircular"); + } + + private void showPropertyDialog() { + if (m_actives.size() != 1) { + return; + } // if + + m_ui.showPropertyDialog(m_actives.get(0)); + fireAction(); + } + + public void setUi(UiBridge a_ui) { + m_ui = a_ui; + } + + + + public void selectNext() { + if (m_root == null) { + return; + } // if + + m_root.selectNext(); + fireAction(); + } + + public void delete() { + if (m_root == null) + return; + if (!m_actives.hasSelected()) { + return; + } // if + + m_root.remove(); + + fireAction(); + } + + public void cutToClipboard() { + if (m_root == null) + return; + if (!m_actives.hasSelected()) { + return; + } // if + + copyToClipboard(); + delete(); + + fireAction(); + } + + public void copyToClipboard() { + if (m_root == null) + return; + if (!m_actives.hasSelected()) { + return; + } // if + + String s = m_actives.getSelectedAsString(); + if (s.equals("")) { + return; + } // if + + StringSelection selection = new StringSelection(s); + + try { + m_clipboard.setContents(selection, selection); + } catch (Exception e) { + e.printStackTrace(); + } // try-catch + + fireAction(); + } + + public void pasteFromClipboard() { + if (m_root == null) + return; + Transferable content = null; + String s = ""; + + try { + content = m_clipboard.getContents(this); + if (content == null) + return; + s = (String) content.getTransferData(DataFlavor.stringFlavor); + if (s.equals("")) { + return; + } // if + } catch (Exception e) { + e.printStackTrace(); + return; + } // try-catch + + try { + m_root.addObjectFromClipboard(s); + } catch (GlyphFile.CircularIncludeException e) { + Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, m_msgCircular, e); + } + + fireAction(); + } + + public void undo() { + if (m_root == null) + return; + + m_root.undo(); + fireAction(); + } + + public void redo() { + if (m_root == null) + return; + + m_root.redo(); + fireAction(); + } + + public void setAdvanceWidth(int a_value) { + if (m_root == null) + return; + + m_root.setAdvanceWidth(a_value); + fireAction(); + } + + public void moveLeft() { + move(new Point2D.Double(-1, 0)); + } + + public void moveUp() { + move(new Point2D.Double(0, 1)); + } + + public void moveDown() { + move(new Point2D.Double(0, -1)); + } + + public void moveRight() { + move(new Point2D.Double(1, 0)); + } + + private void move(Point2D a_delta) { + if (m_root == null) { + return; + } // if + + m_root.move(a_delta); + } + + public void buildNewTypeface(String a_name, File a_dir) throws FileNotFoundException { + if (a_name == null || a_name.equals("")) { + return; + } // if + + TypefaceFile typeface = new TypefaceFile(a_name, a_dir); + typeface.setAuthor("no body"); + DateFormat format = new SimpleDateFormat("yyyy"); + typeface.setCopyrightYear(format.format(new Date())); + typeface.setFontFamilyName(a_name); + typeface.setSubFamily("Regular"); + typeface.addCodePage(TTCodePage.US_ASCII.toString()); + typeface.addCodePage(TTCodePage.Latin_1.toString()); + + setTypeface(typeface); + } + + public void addDefaultGlyphs() throws FileNotFoundException { + m_typeface.addRequiredGlyphs(); + m_typeface.addBasicLatinGlyphs(); + + fireAction(); + } + + public void openTypeface() throws FileNotFoundException { + if (m_chooser == null) { + m_chooser = new JFileChooser(new File(AppSettings.getLastTypefaceDir())); + } // if + + m_chooser.setFileFilter(new TypefaceFileFilter()); + int returnVal = m_chooser.showOpenDialog(null); + + if (returnVal != JFileChooser.APPROVE_OPTION) { + return; + } // if + + AppSettings.setLastTypefaceDir(m_chooser.getSelectedFile().toString()); + openTypeface(m_chooser.getSelectedFile()); + } + + private void openTypeface(File a_file) throws FileNotFoundException { + setTypeface(new TypefaceFile(a_file)); + + if (m_typeface.addRequiredGlyphs()) { + fireAction(); + } // if + } + + public void setTypeface(TypefaceFile a_typeface) { + m_typeface = a_typeface; + fireAction(); + } + + public void changeUnicode(long a_unicode) throws FileNotFoundException { + if (m_typeface == null || m_root == null) { + return; + } // if + + m_typeface.setGlyphUnicode(m_root, a_unicode); + fireAction(); + } + + public int findFile(long a_unicode) { + if (m_typeface == null) + return USER_CANCELLED; + + m_foundFileName = m_typeface.unicodeToFileName(a_unicode); + if (m_foundFileName != null) { + return FILE_FOUND; + } // if + + return FILE_NOT_FOUND; + } + + public String getFoundFileName() { + return m_foundFileName; + } + + + /** + * Create glyph out of given unicode, and add it to the typeface. + * @param a_unicode + */ + public GlyphFile addNewGlyph(long a_unicode) throws FileNotFoundException { + GlyphFile retval; + + retval = m_typeface.createGlyph(a_unicode); + addGlyphToTypeface(retval); + + return retval; + } + + public void checkUnicodeBlock(long a_unicode) throws FileNotFoundException { + TTUnicodeRange range = TTUnicodeRange.of(a_unicode); + if (range == null){ + return; + } + + if (m_typeface.containsUnicodeRange(range.toString())){ + return; + } + m_typeface.addUnicodeRange(range.toString()); + } + + private void addGlyphToTypeface(GlyphFile a_file) throws FileNotFoundException { + m_typeface.addGlyph(a_file); + m_typeface.saveGlyphFile(); + + setRoot(a_file); + } + + public GlyphFile openGlyphFile(String a_fileName) { + ModuleManager manager = ModuleManager.getSingletonInstance(); + GlyphFile retval = manager.getReloadedGlyphFile(a_fileName); + setRoot(retval); + + return retval; + } + + public void removeGlyphFromTypeface(String a_fileName) { + if (m_typeface == null) + return; + + m_typeface.removeGlyph(a_fileName); + fireAction(); + } + + public Font buildTrueType(boolean a_isDebug) { + Font retval = null; + + if (m_typeface == null) + return retval; + + + + try { + m_typeface.buildTTF(a_isDebug); + retval = m_typeface.getFont(); + } catch (Exception e) { + Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, null,e); + } // try-catch + + return retval; + } + + public void saveGlyph() throws FileNotFoundException { + if (m_root == null) + return; + + if (m_root.getGlyphTitle().equals("")) { + Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, m_msgEmptyGlyphTitle); + return; + } // if + + m_root.saveGlyphFile(); + fireAction(); + } + + public TypefaceFile getTypeface() { + return m_typeface; + } + + public File getGlyphPath() { + return m_typeface.getGlyphPath(); + } + + + public GlyphFile getRoot() { + return m_root; + } + + public void setRoot(GlyphFile a_file) { + m_root = a_file; + fireAction(); + } + + public void addActionListener(ActionListener a_listener) { + m_listeners.add(a_listener); + } + + public void fireAction() { + ActionEvent e = new ActionEvent(this, Event.ACTION_EVENT, "foo"); + + for (ActionListener listener: m_listeners) { + listener.actionPerformed(e); + } // for listener + } + + public String includeFileName() { + String retval = ""; + + JFileChooser chooser = new JFileChooser(getGlyphPath()); + chooser.setFileFilter(new GlyphFileFilter()); + + int returnVal = chooser.showOpenDialog(null); + + if (returnVal == JFileChooser.APPROVE_OPTION) { + retval = chooser.getSelectedFile().getName().toString(); + } // if + + return retval; + } + + public void addCodePage(String a_codePage) throws FileNotFoundException { + if (m_typeface == null) { + return; + } // if + + m_typeface.addCodePage(a_codePage); + fireAction(); + } + + public void removeCodePage(String a_codePage) throws FileNotFoundException { + if (m_typeface == null) { + return; + } // if + + m_typeface.removeCodePage(a_codePage); + fireAction(); + } + + public void setAuthor(String a_value) throws FileNotFoundException { + if (m_typeface == null) { + return; + } // if + + m_typeface.setAuthor(a_value); + m_typeface.saveGlyphFile(); + fireAction(); + } + + public void setCopyrightYear(String a_value) throws FileNotFoundException { + if (m_typeface == null) { + return; + } // if + + m_typeface.setCopyrightYear(a_value); + m_typeface.saveGlyphFile(); + fireAction(); + } + + public void setFontFamilyName(String a_value) throws FileNotFoundException { + if (m_typeface == null) { + return; + } // if + + m_typeface.setFontFamilyName(a_value); + fireAction(); + } + + public void setTypefaceLicense(String a_value) throws FileNotFoundException { + if (m_typeface == null) { + return; + } // if + + m_typeface.setLicense(a_value); + m_typeface.saveGlyphFile(); + fireAction(); + } + + public void setBaseline(double a_value) throws FileNotFoundException { + if (m_typeface == null) { + return; + } // if + + double min = m_typeface.getBottomSideBearing(); + double max = m_typeface.getMeanline(); + + if (a_value < min) { + a_value = min; + } // if + + if (a_value > max) { + a_value = max; + } // if + + try { + m_typeface.setDescender(a_value - min); + m_typeface.setAscender(m_typeface.getEm() + - m_typeface.getTopSideBearing() - a_value); + m_typeface.setXHeight(max - a_value); + } + catch (OutOfRangeException e) { + e.printStackTrace(); + } // try-catch + + fireAction(); + } + + public void setMeanline(double a_value) throws FileNotFoundException { + if (m_typeface == null) { + return; + } // if + + double min = m_typeface.getBaseline(); + double max = m_typeface.getEm() + - m_typeface.getTopSideBearing(); + + if (a_value < min) { + a_value = min; + } // if + + if (a_value > max) { + a_value = max; + } // if + + try { + m_typeface.setXHeight(a_value - min); + } + catch (OutOfRangeException e) { + e.printStackTrace(); + } // try-catch + + fireAction(); + } + + public void mousePressed(MouseEvent a_event) { + + } + + + public void mouseDragged(MouseEvent a_event) { + + } + + public void mouseReleased(MouseEvent a_event) { + + } + + public void setAction(String a_key) { + + } + + public void keyPressed(KeyEvent a_event) { + if (a_event.getModifiers() == 0) { + if (a_event.getKeyCode() == KeyEvent.VK_TAB) { + + m_selectNextAction.actionPerformed(null); + } // if + } else if (a_event.getModifiers() == KeyEvent.SHIFT_MASK) { + + } // if + + fireAction(); + } + + private JFileChooser createImageChooser() { + JFileChooser retval; + + retval = new JFileChooser(new File(AppSettings.getLastTypefaceDir())); + retval.setFileFilter(new javax.swing.filechooser.FileFilter() { + public boolean accept(File a_file) { + if (a_file.isDirectory()) + return true; + + String s = a_file.toString().toLowerCase(); + if (s.endsWith(".gif") + || s.endsWith(".jpg") + || s.endsWith(".jpeg") + || s.endsWith(".png")) + return true; + + return false; + } + + //The description of this filter + public String getDescription() { + return "Image Files"; + } + }); + + return retval; + } + + + + + public ArrayList getPixelSizes() { + return TTPixelSize.getList(); + } + + class MyTreeListener implements TreeSelectionListener { + public void valueChanged(TreeSelectionEvent a_event) { + TreePath path = a_event.getPath(); + Object obj = path.getLastPathComponent(); + String s = obj.toString(); + + TreePath parent = path.getParentPath(); + if (parent != null) { + obj = parent.getLastPathComponent(); + s = obj.toString() + "->" + s; + } // if + + } + } + +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/GlyphColor.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/GlyphColor.java new file mode 100644 index 000000000..fa6bb987a --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/GlyphColor.java @@ -0,0 +1,67 @@ +/* + * $Id: GlyphColor.java,v 1.6 2004/07/11 06:25:11 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa; + +import java.awt.*; + + +/** + * @author e.e + */ +public class GlyphColor { + public static Color MAROON = new Color(120, 21, 11); + public static Color ORANGE = new Color(231, 113, 18); // (238, 176, 55); + public static Color OLIVE = new Color(98, 106, 7); + public static Color INDIGO = new Color(22, 16, 149); + public static Color GREEN = new Color(21, 142, 5); + public static Color RED = new Color(250, 0, 0); + public static Color GRAY = new Color(0x33, 0x33, 0x33); + public static Color CYAN = new Color(15, 187, 157); // 15, 108, 140 + public static Color AZURE = new Color(0x00, 0x66, 0xcc); + public static Color TAN = new Color(0xcc, 0x99, 0x66); + public static Color SILVER = new Color(0xe0, 0xdf, 0xe3); + + + public static Color BACKGROUND = Color.WHITE; + public static Color CROSS = Color.LIGHT_GRAY; + public static Color POINT = ORANGE; + public static Color NUMBER = Color.GRAY; + public static Color SELECTED = RED; + public static Color CONTOUR = AZURE; + public static Color HINT = OLIVE; + public static Color INCLUDE = OLIVE; + public static Color MODULE = MAROON; +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/GlyphFileFilter.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/GlyphFileFilter.java new file mode 100644 index 000000000..b93ba5a42 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/GlyphFileFilter.java @@ -0,0 +1,60 @@ +/* + * $Id: GlyphFileFilter.java,v 1.2 2004/01/20 03:35:27 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003-2004, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa; + +import java.io.File; +import javax.swing.filechooser.FileFilter; + +/** + * @author e.e + */ +public class GlyphFileFilter extends FileFilter { + public boolean accept(File a_file) { + if (a_file.isDirectory()) { + return false; + } // if + + if (! (a_file.toString().toLowerCase().endsWith(".glyph"))) + return false; + + return true; + } + + //The description of this filter + public String getDescription() { + return "glyph files"; + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/HistoryList.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/HistoryList.java new file mode 100644 index 000000000..53fe5e867 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/HistoryList.java @@ -0,0 +1,104 @@ + /* + * $Id: HistoryList.java,v 1.1 2004/09/05 17:08:03 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2004, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa; + +import java.util.*; +import org.doubletype.ossa.module.GlyphFile; + +/** Caretaker of MementoPattern. + * @author e.e + */ +public class HistoryList { + private GlyphFile m_file; + private ArrayList m_list = new ArrayList<>(); + private int m_index = -1; + + + public HistoryList(GlyphFile a_file) { + m_file = a_file; + } + + private void printHistoryArray() { + int i; + for (i = 0; i <= m_index; i++) { + Memento memento = m_list.get(i); + System.out.println(memento.toString()); + } // for i + } + + /** + * Records snapshot into history queue. + * Takes place after each action. + * Updates modified time with the current system time. + * @param a_description + */ + public void record(String a_description) { + add(m_file.createMemento(a_description)); + } + + private void add(Memento a_memento) { + while (m_list.size() - 1 > m_index) { + m_list.remove(m_list.size() - 1); + } // if + + m_list.add(a_memento); + m_index = m_list.size() - 1; + } + + public void undo() { + if (m_list.size() == 0 + || m_index <= 0) { + return; + } // if + + m_index--; + m_file.restore(get(m_index)); + } + + public void redo() { + if (m_list.size() == 0 + || m_index >= m_list.size() - 1) { + return; + } // if + + m_index++; + m_file.restore(get(m_index)); + } + + private Memento get(int a_index) { + return m_list.get(a_index); + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/ImageSizer.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/ImageSizer.java new file mode 100644 index 000000000..dd409e8f7 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/ImageSizer.java @@ -0,0 +1,91 @@ +/* + * $Id: ImageSizer.java,v 1.1 2004/03/04 12:52:50 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003-2004, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa; + +import java.awt.*; +import java.awt.image.*; + +/** + * @author e.e + */ +public class ImageSizer { + private Dimension m_size = new Dimension(-1, -1); + private boolean m_isImcomplete; + + private ImageObserver m_observer = new ImageObserver() { + public synchronized boolean imageUpdate( + Image a_image, + int a_flag, + int a_x, + int a_y, + int a_width, + int a_height) { + if ((a_flag & WIDTH) != 0) + m_size.width = a_width; + if ((a_flag & HEIGHT) != 0) + m_size.height = a_height; + if ((a_flag & (ERROR | ABORT)) != 0) + m_isImcomplete = true; + + boolean retval = !resultKnown(); + if (!retval) { + notifyAll(); + } // if + + return retval; + } + }; + + public ImageSizer(Image a_image) { + m_size.width = a_image.getWidth(m_observer); + m_size.height = a_image.getHeight(m_observer); + } + + private boolean resultKnown() { + return m_size.width != -1 + && m_size.height != -1 + || m_isImcomplete; + } + + //returns null iff error or abort + public Dimension getImageSize() throws InterruptedException { + synchronized (m_observer) { + while (!resultKnown()) + m_observer.wait(); + return m_isImcomplete ? null : new Dimension(m_size); + } + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/Memento.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/Memento.java new file mode 100644 index 000000000..19661eedc --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/Memento.java @@ -0,0 +1,89 @@ + /* + * $Id: Memento.java,v 1.1 2004/09/05 17:08:03 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003 - 2004, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa; + +import java.io.*; +import java.util.zip.*; + +/** + * @author e.e + */ +public class Memento { + private String m_description; + private byte [] m_compressed; + private int m_originalSize; + private long m_entryTime; + + public Memento(String a_description, byte [] a_data) { + m_description = a_description; + m_originalSize = a_data.length; + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ZipOutputStream zip = new ZipOutputStream(out); + + try { + zip.putNextEntry(new ZipEntry(a_description)); + zip.write(a_data); + zip.closeEntry(); + zip.close(); + } + catch (IOException ioe) { + ioe.printStackTrace(); + } + + m_compressed = out.toByteArray(); + m_entryTime = System.currentTimeMillis(); + } + + public InputStream getData() { + ZipInputStream zip = null; + + try { + zip = new ZipInputStream( + new ByteArrayInputStream(m_compressed)); + ZipEntry entry = zip.getNextEntry(); + } + catch (IOException ioe) { + ioe.printStackTrace(); + } + + return zip; + } + + public String toString() { + return m_description; + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/ModuleManager.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/ModuleManager.java new file mode 100644 index 000000000..f1a6e7f92 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/ModuleManager.java @@ -0,0 +1,96 @@ +/* + * $Id: ModuleManager.java,v 1.5 2004/01/14 06:49:39 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa; + +import java.util.*; +import org.doubletype.ossa.module.*; +import java.io.*; + +/** + * @author e.e + */ +public class ModuleManager { + private static ModuleManager s_singleton = null; + + public static ModuleManager getSingletonInstance() { + if (s_singleton == null) + s_singleton = new ModuleManager(); + return s_singleton; + } + + + private Hashtable m_modules = new Hashtable<>(); + private Hashtable m_files = new Hashtable<>(); + + private ModuleManager() { + } + + public void clear() { + m_modules.clear(); + m_files.clear(); + } + + public GlyphModule getModule(String a_name) throws Exception { + if (m_modules.containsKey(a_name)) { + return (GlyphModule) m_modules.get(a_name); + } // if + + GlyphModule retval; + + retval = (GlyphModule) Class.forName(a_name).newInstance(); + m_modules.put(a_name, retval); + + return retval; + } + + public GlyphFile getGlyphFile(String a_name) { + if (m_files.containsKey(a_name)) { + return (GlyphFile) m_files.get(a_name); + } // if + + return getReloadedGlyphFile(a_name); + } + + public GlyphFile getReloadedGlyphFile(String a_name) { + GlyphFile retval; + + Engine engine = Engine.getSingletonInstance(); + retval = new GlyphFile(new File(engine.getGlyphPath(), a_name)); + m_files.put(a_name, retval); + + return retval; + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/MyTableModel.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/MyTableModel.java new file mode 100644 index 000000000..24f671dd6 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/MyTableModel.java @@ -0,0 +1,73 @@ +/* + * $Id: MyTableModel.java,v 1.1 2004/02/09 05:34:17 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003-2004, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa; + +import javax.swing.table.*; +import org.doubletype.ossa.module.*; + +/** + * @author e.e + */ +public class MyTableModel extends AbstractTableModel { + protected Engine m_engine; + protected GlyphFile m_file = null; + + protected MyTableModel(Engine a_engine) { + m_engine = a_engine; + } + + public int getColumnCount() { + return 2; + } + + public int getRowCount() { + reset(); + + return 0; + } + + public Object getValueAt(int a_row, int a_column) { + reset(); + + Object retval = null; + + return retval; + } + + protected void reset() { + + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/OutOfRangeException.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/OutOfRangeException.java new file mode 100644 index 000000000..4016eabe9 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/OutOfRangeException.java @@ -0,0 +1,49 @@ +/* + * $Id: OutOfRangeException.java,v 1.1 2004/02/23 14:19:30 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa; + +/** + * @author e.e + */ +public class OutOfRangeException extends Exception { + private double m_value; + + public OutOfRangeException(double a_value) { + super(); + + m_value = a_value; + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/Renderer.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/Renderer.java new file mode 100644 index 000000000..623e6739f --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/Renderer.java @@ -0,0 +1,44 @@ +/* + * $Id: Renderer.java,v 1.1 2004/06/18 09:14:01 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2004, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa; + +/** + * @author e.e + */ +public interface Renderer { + boolean isRenderNeeded(); + void render(java.awt.Graphics2D a_graphics); +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/Tabbable.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/Tabbable.java new file mode 100644 index 000000000..bc9f0e23c --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/Tabbable.java @@ -0,0 +1,5 @@ +package org.doubletype.ossa; + +public interface Tabbable { + boolean isClosable(); +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/TabbedPaneCloseButtonUI.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/TabbedPaneCloseButtonUI.java new file mode 100644 index 000000000..0d9504efc --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/TabbedPaneCloseButtonUI.java @@ -0,0 +1,188 @@ +// http://forums.sun.com/thread.jspa?forumID=257&threadID=453521 + +package org.doubletype.ossa; + +import java.awt.Color; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Rectangle; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; + +import javax.swing.plaf.basic.BasicTabbedPaneUI; + +public class TabbedPaneCloseButtonUI extends BasicTabbedPaneUI { + private final int k_xButtonOffset = 19; + private final int k_yButtonOffset = 4; + private final int k_wButton = 14; // was 13 + private final int k_hButton = 13; // was 12 + + private int m_lastKnownSelected = -1; + private Color m_red = new Color(217, 76, 74); + private Color m_selectedColor = Color.white; + private Color m_unselectedColor = new Color(160, 197, 241); + + public TabbedPaneCloseButtonUI() { + super(); + } + + protected void paintTabBackground(Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h, boolean isSelected) + { + if (isSelected) + { + g.setColor(m_selectedColor); + } + else + { + g.setColor(m_unselectedColor); + } + + g.fillRect(x, y, w, h); + } + + protected int calculateTabHeight(int tabPlacement, int tabIndex, int fontHeight) + { + return fontHeight + 4; + } + + protected void paintTabBorder(Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h, boolean isSelected) + { + g.setColor(darkShadow); + g.drawLine(x, y + h - 2, x, y); + g.drawLine(x, y, x + w, y); + g.drawLine(x + w, y + h - 2, x + w, y); + } + + protected void paintTab(Graphics g, int tabPlacement, Rectangle[] rects, + int tabIndex, Rectangle iconRect, Rectangle textRect) { + + super.paintTab(g, tabPlacement, rects, tabIndex, iconRect, textRect); + } + + protected void paintFocusIndicator(Graphics g, int tabPlacement, Rectangle[] rects, int tabIndex, Rectangle iconRect, Rectangle textRect, boolean isSelected) + { + } + + protected void paintContentBorderTopEdge(Graphics g, int tabPlacement, int selectedIndex, int x, int y, int w, int h) + { + if (selectedIndex < 0) { + return; + } // if + + Rectangle rect = getTabBounds(selectedIndex, calcRect); + g.setColor(darkShadow); + g.drawLine(x, y, rect.x, y); + g.drawLine(rect.x + rect.width, y, x + w, y); + g.setColor(m_selectedColor); + g.drawLine(rect.x + 1, y, rect.x + rect.width -1, y); + } + + protected void paintContentBorderBottomEdge(Graphics g, int tabPlacement, int selectedIndex, int x, int y, int w, int h) + { + } + + protected void paintContentBorderRightEdge(Graphics g, int tabPlacement, int selectedIndex, int x, int y, int w, int h) + { + } + + protected void paintContentBorderLeftEdge(Graphics g, int tabPlacement, int selectedIndex, int x, int y, int w, int h) + { + } + + protected void paintText(Graphics g, int tabPlacement, java.awt.Font font, FontMetrics metrics, int tabIndex, String title, Rectangle textRect, boolean isSelected) + { + if (tabPane.getComponentAt(tabIndex) instanceof Tabbable) { + Tabbable tabbable = (Tabbable) tabPane.getComponentAt(tabIndex); + if (!tabbable.isClosable()) { + super.paintText(g, tabPlacement, font, metrics, tabIndex, title, textRect, isSelected); + return; + } // if + } // if + + if (isSelected) // isSelected + { + super.paintText(g, tabPlacement, font, metrics, tabIndex, title, textRect, isSelected); + Rectangle rect = rects[tabIndex]; + g.setColor(m_red); + int xButton = rect.x + rect.width - k_xButtonOffset; // -19 + int yButton = rect.y + k_yButtonOffset; // +4 + g.fillRect(xButton, yButton, k_wButton, k_hButton); + g.setColor(Color.white); + g.drawLine(xButton + 3, rect.y + 7, xButton + 9, rect.y + 13); + g.drawLine(xButton + 9, rect.y + 7, xButton + 3, rect.y + 13); + g.drawLine(xButton + 4, rect.y + 7, xButton + 10, rect.y + 13); + g.drawLine(xButton + 10, rect.y + 7, xButton + 4, rect.y + 13); + + m_lastKnownSelected = tabIndex; + } + else + { + super.paintText(g, tabPlacement, font, metrics, tabIndex, title, textRect, isSelected); + } + } + + protected int calculateTabWidth(int tabPlacement, int tabIndex, + FontMetrics metrics) { + if (tabPane.getComponentAt(tabIndex) instanceof Tabbable) { + Tabbable tabbable = (Tabbable) tabPane.getComponentAt(tabIndex); + if (!tabbable.isClosable()) { + return super.calculateTabWidth(tabPlacement, tabIndex, metrics); + } // if + } // if + + return super.calculateTabWidth(tabPlacement, tabIndex, metrics) + 34; // +24 + } + + protected MouseListener createMouseListener() { + return new MyMouseHandler(); + } + + class MyMouseHandler extends MouseHandler { + private int m_selectedOnPressed = -1; + + public MyMouseHandler() { + super(); + } + + public void mousePressed(MouseEvent e) { + m_selectedOnPressed = m_lastKnownSelected; + super.mousePressed(e); + } + + public void mouseReleased(MouseEvent e) { + int x = e.getX(); + int y = e.getY(); + int tabIndex = -1; + int tabCount = tabPane.getTabCount(); + for (int i = 0; i < tabCount; i++) { + if (rects[i].contains(x, y)) { + tabIndex = i; + break; + } // if + } // for i + + // skip if this is not current. + if (tabPane.getSelectedIndex() != tabIndex) { + return; + } // if + + if (m_selectedOnPressed != tabIndex) { + return; + } // if + + if (tabIndex >= 0 && !e.isPopupTrigger()) { + Rectangle tabRect = rects[tabIndex]; + y = y - tabRect.y; + + int xButton = tabRect.x + tabRect.width - k_xButtonOffset; + if ((x >= xButton + 1) + && (x <= xButton + k_wButton - 2) + && (y >= k_yButtonOffset + 1) + && (y <= k_yButtonOffset + k_hButton - 2)) { + tabPane.remove(tabIndex); + } + } + } + } + +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/TypefaceFileFilter.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/TypefaceFileFilter.java new file mode 100644 index 000000000..446cdad16 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/TypefaceFileFilter.java @@ -0,0 +1,59 @@ +/* + * $Id: TypefaceFileFilter.java,v 1.1 2004/01/20 03:35:27 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003-2004, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa; + +import java.io.File; +import javax.swing.filechooser.FileFilter; + +/** + * @author e.e + */ +public class TypefaceFileFilter extends FileFilter { + public boolean accept(File a_file) { + if (a_file.isDirectory()) + return true; + + if (! (a_file.toString().toLowerCase().endsWith(".dtyp"))) + return false; + + return true; + } + + //The description of this filter + public String getDescription() { + return "typeface files"; + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/UiBridge.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/UiBridge.java new file mode 100644 index 000000000..c49d75c7d --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/UiBridge.java @@ -0,0 +1,12 @@ +/* + */ +package org.doubletype.ossa; + +import org.doubletype.ossa.adapter.*; + +/** + * @author e.e + */ +public interface UiBridge { + void showPropertyDialog(GlyphObject a_object); +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/UnicodeBuilder.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/UnicodeBuilder.java new file mode 100644 index 000000000..b10718938 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/UnicodeBuilder.java @@ -0,0 +1,184 @@ +/* + * $Id: UnicodeBuilder.java,v 1.1 2004/09/11 10:09:07 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2004, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa; + +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.CharacterCodingException; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.util.logging.Level; +import java.util.logging.Logger; + + +/** + * @author e.e + */ +public class UnicodeBuilder { + public static final String k_jisCharset = "ISO-2022-JP"; + + /** + * pops dialog and asks user for unicode. + * @return true on success, false otherwise. + */ + public static Long askUnicode() { + Engine engine = Engine.getSingletonInstance(); + + throw new UnsupportedOperationException(); + } + + public static Long build(String a_value, int a_option) { + if (a_value == null + || a_value.length() == 0) { + return null; + } // if + + switch (a_option) { + case Engine.SEARCH_BY_EXAMPLE: { + return buildByExample(a_value); + } // case + + case Engine.SEARCH_UNICODE: { + return buildByUnicode(a_value); + } // case + + case Engine.SEARCH_JIS_CODE: { + return buildByJisCode(a_value); + } // case + } // switch + + return null; + } + + private static Long buildByExample(String a_value) { + if (a_value.length() > 1) { + return null; + } // if + + return new Long((long) a_value.charAt(0)); + } + + private static Long buildByUnicode(String a_value) { + if (a_value.length() == 1) { + return buildByExample(a_value); + } // if + + try { + return new Long(Long.parseLong(a_value, 16)); + } catch (NumberFormatException e) { + Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, null,e); + } + + return null; + } + + private static Long buildByJisCode(String a_value) { + if (a_value.length() == 1) { + return buildByExample(a_value); + } // if + + try { + Long retval = jisX0208ToUnicode(Long.parseLong(a_value, 16)); + + if (retval == null) { + Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, "Bad JIS Code."); + } // if + + return retval; + } catch (NumberFormatException e) { + Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, null, e); + } // try + + return null; + } + + /** + * converts JIS X0208 code into unicode using ISO-2022-JP decoder. + * @param a_value JIS code + * @return unicode + */ + public static Long jisX0208ToUnicode(long a_value) { + if (!isJisSupported()) { + return null; + } // if + + Charset jis = Charset.forName(k_jisCharset); + ByteBuffer in = ByteBuffer.allocate(5); + CharsetDecoder jisDecoder; + jisDecoder = jis.newDecoder(); + + long high = (0xff00 & a_value) >> 8; + long low = 0x00ff & a_value; + + if (high < 0x21 || high > 0x7e || low < 0x21 || high > 0x7e) { + return null; + } // if + + char c = (char) a_value; + + in.rewind(); + in.put((byte) 0x1b); + in.put((byte) 0x24); + in.put((byte) 0x40); + + in.putChar(c); + in.position(0); + + try { + CharBuffer out = jisDecoder.decode(in); + if (out.length() > 0) { + return new Long(out.get(0)); + } // if + } catch (CharacterCodingException e) { + e.printStackTrace(); + } // try-catch + + return null; + } + + public static boolean isJisSupported() { + return Charset.isSupported(k_jisCharset); + } + + /** + * + */ + public UnicodeBuilder() { + super(); + // TODO Auto-generated constructor stub + } + +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/CubicSegment.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/CubicSegment.java new file mode 100644 index 000000000..44c33e025 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/CubicSegment.java @@ -0,0 +1,398 @@ +/* + * $Id: CubicSegment.java,v 1.2 2004/12/27 04:56:02 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2004, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa.adapter; + +import java.util.*; +import java.awt.geom.*; + +import org.doubletype.ossa.xml.*; + +/** + * @author e.e + */ +public class CubicSegment { + public static final int LINE = 0; + public static final int CURVE = 1; + + private static final double k_tolerance = 5; + private static final double k_minTolerance = 10; + private static final int k_maxTrial = 3; + + /** + * converts cubic contour into cubic segments. + * @param a_contour + * @return + */ + public static ArrayList toSegments(EContour a_contour) { + ArrayList retval = new ArrayList<>(); + XContourPoint [] points = a_contour.getContourPoint(); + if (points.length < 2) { + return retval; + } // if + + EContourPoint startPoint = (EContourPoint) points[points.length - 1]; + for (int i = 0; i < points.length; i++) { + EContourPoint endPoint = (EContourPoint) points[i]; + retval.add(new CubicSegment(startPoint, endPoint)); + startPoint = endPoint; + } // for + + return retval; + } + + /** + * converts cubic segments into cubic contour. + * @param a_segments + * @return + */ + public static EContour toContour(ArrayList a_segments) { + EContour retval = new EContour(); + retval.setType(EContour.k_cubic); + + EControlPoint controlPoint1 = null; + for (int i = 0; i < a_segments.size(); i++) { + CubicSegment segment = (CubicSegment) a_segments.get(i); + EContourPoint startPoint = (EContourPoint) segment.m_startPoint.clone(); + + if (controlPoint1 != null) { + startPoint.setControlPoint1(controlPoint1); + controlPoint1 = null; + } // if + + if (segment.m_controlPoint1 != null) { + EControlPoint controlPoint2 = new EControlPoint(false, + segment.m_controlPoint1.getX(), + segment.m_controlPoint1.getY()); + startPoint.setControlPoint2(controlPoint2); + } // if + + retval.addContourPoint(startPoint); + + if (segment.m_controlPoint2 != null) { + controlPoint1 = new EControlPoint(true, + segment.m_controlPoint2.getX(), + segment.m_controlPoint2.getY()); + } + } // for i + + return retval; + } + + private EContourPoint m_startPoint = null; + private EContourPoint m_controlPoint1 = null; + private EContourPoint m_controlPoint2 = null; + private EContourPoint m_endPoint = null; + + private int m_type = LINE; + + + public CubicSegment(EContourPoint a_startPoint, EContourPoint a_endPoint) { + m_startPoint = a_startPoint; + m_endPoint = a_endPoint; + + if ((!a_startPoint.hasControlPoint2()) && (!a_endPoint.hasControlPoint1())) { + m_type = LINE; + return; + } // if + + if (a_startPoint.hasControlPoint2() || a_endPoint.hasControlPoint1()) { + m_type = CURVE; + + if (a_startPoint.hasControlPoint2()) { + m_controlPoint1 = (EContourPoint) a_startPoint.getControlPoint2().getContourPoint(); + } else { + m_controlPoint1 = a_startPoint; + } // if-else + + if (a_endPoint.hasControlPoint1()) { + m_controlPoint2 = (EContourPoint) a_endPoint.getControlPoint1().getContourPoint(); + } else { + m_controlPoint2 = a_endPoint; + } // if-else + } // if + } + + public CubicSegment(EContourPoint a_startPoint, EContourPoint a_controlPoint1, + EContourPoint a_controlPoint2, EContourPoint a_endPoint) { + m_startPoint = a_startPoint; + m_controlPoint1 = a_controlPoint1; + m_controlPoint2 = a_controlPoint2; + m_endPoint = a_endPoint; + m_type = CURVE; + } + + public ArrayList toQuadraticSegments() { + ArrayList retval = new ArrayList<>(); + + if (m_type == LINE) { + retval.add(new QuadraticSegment(m_startPoint, null, m_endPoint)); + return retval; + } // if + + return toQuadraticSegments(0); + } + + //JPEXS start + private static Point2D.Double movePoint(Point2D point, double dx, double dy) { + return new Point2D.Double(point.getX() + dx, point.getY() + dy); + } + + private static Point2D getMidPoint(Point2D p0, Point2D p1) { + return getPointOnSegment(p0, p1, 0.5); + } + + private static Point2D getPointOnSegment(Point2D p0, Point2D p1, double ratio) { + double x = p0.getX() + ((p1.getX() - p0.getX()) * ratio); + double y = p0.getY() + ((p1.getY() - p0.getY()) * ratio); + return new Point2D.Double(x, y); + } + private static double[][] approximateCubic(double[] cubicControlPointCoords) { + if (cubicControlPointCoords.length < 8) { + throw new IllegalArgumentException("Must have at least 8 coordinates"); + } + + //extract point objects from source array + Point2D p0 = new Point2D.Double(cubicControlPointCoords[0], cubicControlPointCoords[1]); + Point2D p1 = new Point2D.Double(cubicControlPointCoords[2], cubicControlPointCoords[3]); + Point2D p2 = new Point2D.Double(cubicControlPointCoords[4], cubicControlPointCoords[5]); + Point2D p3 = new Point2D.Double(cubicControlPointCoords[6], cubicControlPointCoords[7]); + + //calculates the useful base points + Point2D pa = getPointOnSegment(p0, p1, 3.0 / 4.0); + Point2D pb = getPointOnSegment(p3, p2, 3.0 / 4.0); + + //get 1/16 of the [P3, P0] segment + double dx = (p3.getX() - p0.getX()) / 16.0; + double dy = (p3.getY() - p0.getY()) / 16.0; + + //calculates control point 1 + Point2D pc1 = getPointOnSegment(p0, p1, 3.0 / 8.0); + + //calculates control point 2 + Point2D pc2 = getPointOnSegment(pa, pb, 3.0 / 8.0); + pc2 = movePoint(pc2, -dx, -dy); + + //calculates control point 3 + Point2D pc3 = getPointOnSegment(pb, pa, 3.0 / 8.0); + pc3 = movePoint(pc3, dx, dy); + + //calculates control point 4 + Point2D pc4 = getPointOnSegment(p3, p2, 3.0 / 8.0); + + //calculates the 3 anchor points + Point2D pa1 = getMidPoint(pc1, pc2); + Point2D pa2 = getMidPoint(pa, pb); + Point2D pa3 = getMidPoint(pc3, pc4); + + //return the points for the four quadratic curves + return new double[][]{ + {pc1.getX(), pc1.getY(), pa1.getX(), pa1.getY()}, + {pc2.getX(), pc2.getY(), pa2.getX(), pa2.getY()}, + {pc3.getX(), pc3.getY(), pa3.getX(), pa3.getY()}, + {pc4.getX(), pc4.getY(), p3.getX(), p3.getY()}}; + } + + //JPEXS end + + private ArrayList toQuadraticSegments(int a_trial) { + ArrayList retval = new ArrayList<>(); + + a_trial++; + + double[][] quadCoords =approximateCubic(new double[]{m_startPoint.getX(),m_startPoint.getY(),m_controlPoint1.getX(),m_controlPoint1.getY(),m_controlPoint2.getX(),m_controlPoint2.getY(),m_endPoint.getX(),m_endPoint.getY()}); + EContourPoint lastPoint=m_startPoint; + for (int i = 0; i < quadCoords.length; i++) { + retval.add(new QuadraticSegment( + lastPoint, + new EContourPoint(quadCoords[i][0], quadCoords[i][1], true), + new EContourPoint(quadCoords[i][2], quadCoords[i][3], false))); + lastPoint = new EContourPoint(quadCoords[i][2],quadCoords[i][3],true); + } + /*EContourPoint intersection = calculateIntersection(); + + double deltaX = 0.125 * (m_startPoint.getX() + m_endPoint.getX() + 4 * intersection.getX() + - 3 * (m_controlPoint1.getX() + m_controlPoint2.getX())); + double deltaY = 0.125 * (m_startPoint.getY() + m_endPoint.getY() + 4 * intersection.getY() + - 3 * (m_controlPoint1.getY() + m_controlPoint2.getY())); + double deltaSqr = (deltaX * deltaX + deltaY * deltaY); + + if (deltaSqr > (k_minTolerance * k_minTolerance) + || ((a_trial < k_maxTrial) && (deltaSqr > (k_tolerance * k_tolerance)))) { + return toSplitQuadraticSegments(a_trial); + } // if + + retval.add(new QuadraticSegment(m_startPoint, intersection, m_endPoint));*/ + return retval; + } + + private ArrayList toSplitQuadraticSegments(int a_trial) { + EContourPoint p01 = midPoint(m_startPoint, m_controlPoint1); + EContourPoint p12 = midPoint(m_controlPoint1, m_controlPoint2); + EContourPoint p23 = midPoint(m_controlPoint2, m_endPoint); + + EContourPoint pA = midPoint(p01, p12); + EContourPoint pB = midPoint(p12, p23); + + EContourPoint pAB = midPoint(pA, pB); + + CubicSegment firstCubicSegment = new CubicSegment(m_startPoint, p01, pA, pAB); + CubicSegment secondCubicSegment = new CubicSegment(pAB, pB, p23, m_endPoint); + + ArrayList firstHalf = firstCubicSegment.toQuadraticSegments(a_trial); + ArrayList secondHalf = secondCubicSegment.toQuadraticSegments(a_trial); + + firstHalf.addAll(secondHalf); + + return firstHalf; + } + + private EContourPoint midPoint(EContourPoint a_start, EContourPoint a_end) { + Point2D p = calculateMidPoint(a_start, a_end); + EContourPoint retval = new EContourPoint(p.getX(), p.getY(), true); + + ArrayList ppems = getPpems(a_start, a_end); + EPoint startPoint, endPoint; + for (int i = 0; i < ppems.size(); i++) { + Long ppemObject = (Long) ppems.get(i); + long ppem = ppemObject.longValue(); + + if (retval.hasHintForPpem(ppem)) { + continue; + } // if + + startPoint = a_start.getHintIfPossible(ppem); + endPoint = a_end.getHintIfPossible(ppem); + + p = calculateMidPoint(startPoint, endPoint); + EHint hint = new EHint(p.getX(), p.getY(), ppem); + retval.addHint(hint); + } // for i + + return retval; + } + + private Point2D calculateMidPoint(EPoint a_p1, EPoint a_p2) { + Point2D retval = new Point2D.Double((a_p1.getX() + a_p2.getX()) / 2.0, + (a_p1.getY() + a_p2.getY()) / 2.0); + return retval; + } + + /** + * calculate intersection of line (a_start, a_controlPoint1) and + * line (a_end, a_controlPoint2) + * @return + */ + private EContourPoint calculateIntersection() { + EContourPoint retval = new EContourPoint(m_startPoint.getX(), m_startPoint.getY(), false); + Point2D intersection = calculateIntersection(m_startPoint, m_controlPoint1, m_controlPoint2, m_endPoint); + retval.getPoint2d().setX(intersection.getX()); + retval.getPoint2d().setY(intersection.getY()); + + EPoint startPoint, controlPoint1, controlPoint2, endPoint; + ArrayList ppems = getPpems(m_startPoint, m_controlPoint1, m_controlPoint2, m_endPoint); + for (int i = 0; i < ppems.size(); i++) { + Long ppemObject = (Long) ppems.get(i); + long ppem = ppemObject.longValue(); + + if (retval.hasHintForPpem(ppem)) { + continue; + } // if + + startPoint = m_startPoint.getHintIfPossible(ppem); + controlPoint1 = m_controlPoint1.getHintIfPossible(ppem); + controlPoint2 = m_controlPoint2.getHintIfPossible(ppem); + endPoint = m_endPoint.getHintIfPossible(ppem); + + Point2D p = calculateIntersection(startPoint, controlPoint1, controlPoint2, endPoint); + EHint hint = new EHint(p.getX(), p.getY(), ppem); + retval.addHint(hint); + } // for i + + return retval; + } + + private Point2D calculateIntersection(EPoint a_p1, EPoint a_p2, EPoint a_p3, EPoint a_p4) { + Point2D retval = new Point2D.Double(a_p1.getX(), a_p1.getY()); + + double deltaX1 = a_p2.getX() - a_p1.getX(); + double deltaX2 = a_p3.getX() - a_p4.getX(); + if (deltaX1 == 0) { + deltaX1 = 0.1; + } // if + if (deltaX2 == 0) { + deltaX2 = 0.2; + } // if + + double incline1 = (a_p2.getY() - a_p1.getY()) / deltaX1; + double incline2 = (a_p3.getY() - a_p4.getY()) / deltaX2; + if (incline1 == incline2) { + return retval; + } // if + + double x = (-incline2 * a_p4.getX() + a_p4.getY() + +incline1 * a_p1.getX() - a_p1.getY()) / (incline1 - incline2); + double y = incline1 * (x - a_p1.getX()) + a_p1.getY(); + + retval.setLocation(x, y); + return retval; + } + + private ArrayList getPpems(EContourPoint a_start, EContourPoint a_end) { + ArrayList retval = new ArrayList<>(); + collectPpemsFromHints(retval, a_start.getHint()); + collectPpemsFromHints(retval, a_end.getHint()); + return retval; + } + + private void collectPpemsFromHints(ArrayList a_ppems, XHint[] a_hints) { + for (XHint hint: a_hints) { + if (!a_ppems.contains(hint.getPpem())) { + a_ppems.add(hint.getPpem()); + } // if + } // for i + } + + private ArrayList getPpems(EContourPoint a_start, EContourPoint a_controlPoint1, + EContourPoint a_controlPoint2, EContourPoint a_end) { + ArrayList retval = new ArrayList<>(); + collectPpemsFromHints(retval, a_start.getHint()); + collectPpemsFromHints(retval, a_controlPoint1.getHint()); + collectPpemsFromHints(retval, a_controlPoint2.getHint()); + collectPpemsFromHints(retval, a_end.getHint()); + return retval; + } + +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EContour.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EContour.java new file mode 100644 index 000000000..793b5d894 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EContour.java @@ -0,0 +1,243 @@ +/* + * $Id: EContour.java,v 1.11 2004/12/17 04:13:17 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003-2004, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa.adapter; + +import java.awt.*; +import java.awt.geom.*; +import java.util.ArrayList; + +import org.doubletype.ossa.xml.*; +import org.doubletype.ossa.*; +import org.doubletype.ossa.module.Rectangle; + +/** + * @author e.e + */ +public class EContour extends XContour implements GlyphObject, PointAggregate { + public static final String k_quadratic = "quadratic"; + public static final String k_cubic = "cubic"; + public static final int k_defaultPixelSize = 16; + + public static EContour createAt(Point2D a_point) { + EContour retval = new EContour(); + retval.setType(k_cubic); + + EContourPoint point; + double x, y; + + x = a_point.getX(); + y = a_point.getY(); + point = new EContourPoint(x, y, true); + retval.addContourPoint(point); + + + x += Rectangle.k_defaultPen; + point = new EContourPoint(x, y, true); + retval.addContourPoint(point); + + y += Rectangle.k_defaultPen; + point = new EContourPoint(x, y, true); + retval.addContourPoint(point); + + x -= Rectangle.k_defaultPen; + point = new EContourPoint(x, y, true); + retval.addContourPoint(point); + + return retval; + } + + // -------------------------------------------------------------- + + public EContour() { + initDefaults(); + } + + public EContour(RStack a_stack) { + super(a_stack); + initDefaults(); + } + + /** set default values + */ + private void initDefaults() { + if (getType() == null) { + setType(k_quadratic); + } // if + } + + public boolean isCubic() { + return getType().equals(k_cubic); + } + + public EContour transpose(AffineTransform a_trans) { + EContour retval = new EContour(); + retval.setType(this.getType()); + + XContourPoint[] points = getContourPoint(); + int i; + for (i = 0; i < points.length; i++) { + EContourPoint point = (EContourPoint) points[i]; + retval.addContourPoint(point.transpose(a_trans)); + } // if + + return retval; + } + + // -------------------------------------------------------------- + + public void display(Graphics2D g, AffineTransform a_trans) { + g.setColor(GlyphColor.CONTOUR); + + if (isSelected()) { + g.setColor(GlyphColor.SELECTED); + } // if + + int ppem =EContour.k_defaultPixelSize; + g.draw(toShape(a_trans, ppem)); + } + + public boolean isSelected() { + return EObject.getActives().isSelected(this); + } + + public Shape toShape(AffineTransform a_trans, int a_ppem) { + return transpose(a_trans).toShape(a_ppem); + } + + private Shape toShape(int a_ppem) { + Emulator emulator = Emulator.getInstance(); + + return emulator.createShape(this, a_ppem); + } + + public void move(Point2D a_delta) { + movePoints(getContourPoint(), a_delta); + } + + private void movePoints(XContourPoint [] a_points, Point2D a_delta) { + int i; + for (i = 0; i < a_points.length; i++) { + EContourPoint point = (EContourPoint) a_points[i]; + EObject.movePoint(point, a_delta); + } // for i + } + + public void remove() { + XBody parent = (XBody) rGetParentRNode(); + parent.removeContour(this); + } + + // PointAggregate + public void removePoint(EContourPoint a_point) { + removeContourPoint(a_point); + + if (getContourPoint().length < 2) { + remove(); + } // if + } + + // PointAggregate + public void movePoint(EContourPoint a_point, Point2D a_delta) { + EObject.movePoint(a_point, a_delta); + } + + // PointAggregate + public GlyphObject insertPoint(EContourPoint a_point) { + int i; + int len = getContourPoint().length; + + for (i = 0; i < len; i++) { + if (getContourPoint(i) == a_point) { + break; + } // if + } // for + + EContourPoint nextPoint; + nextPoint = (EContourPoint) getContourPoint((i + 1) % len); + + double x = (a_point.getX() + nextPoint.getX()) / 2; + double y = (a_point.getY() + nextPoint.getY()) / 2; + + EContourPoint retval = new EContourPoint(x, y, true); + addContourPoint(i + 1, retval); + + return retval; + } + + public boolean hit(Rectangle2D a_rect, AffineTransform a_trans) { + return EObject.hit(this, a_rect, a_trans); + } + + public void convert() { + XBody parent = (XBody) rGetParentRNode(); + + if (isCubic()) { + parent.addContour(toQuadratic()); + } else { + parent.addContour(toCubic()); + } // else + + remove(); + } + + public EContour toQuadratic() { + if (!isCubic()) { + return this; + } // if + + ArrayList quadraticSegments = new ArrayList<>(); + for (CubicSegment segment: CubicSegment.toSegments(this)) { + quadraticSegments.addAll(segment.toQuadraticSegments()); + } // for i + + return QuadraticSegment.toContour(quadraticSegments); + } + + public EContour toCubic() { + if (isCubic()) { + return this; + } // if + + ArrayList quadraticSegments = QuadraticSegment.toSegments(this); + ArrayList cubicSegments = new ArrayList<>(); + for (int i = 0; i < quadraticSegments.size(); i++) { + QuadraticSegment quadraticSegment = (QuadraticSegment) quadraticSegments.get(i); + cubicSegments.add(quadraticSegment.toCubicSegment()); + } // for i + + return CubicSegment.toContour(cubicSegments); + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EContourPoint.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EContourPoint.java new file mode 100644 index 000000000..e28994177 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EContourPoint.java @@ -0,0 +1,419 @@ +/* + * $Id: EContourPoint.java,v 1.10 2004/12/27 04:56:02 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2004, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa.adapter; + +import org.doubletype.ossa.*; +import org.doubletype.ossa.xml.*; +import java.awt.*; +import java.awt.geom.*; + +/** + * @author e.e + */ +public class EContourPoint extends XContourPoint implements GlyphObject, EPoint { + public static String k_on = "on"; + public static String k_off = "off"; + public static String k_true = "true"; + public static String k_false = "false"; + + private int m_number = 0; + + /** offset of this from the global coord. + * For contours, it will be 0. + * For module invoke, it will be pos.x. + */ + private double m_xOffset = 0; + private double m_yOffset = 0; + + private Point2D m_adjusted; + + public EContourPoint() { + super(); + } + + public EContourPoint(RStack a_stack) { + super(a_stack); + correctControlPoint(); + } + + public EContourPoint(double a_x, double a_y, boolean a_isOn) { + setPoint2d(new XPoint2d()); + getPoint2d().setX(a_x); + getPoint2d().setY(a_y); + + setOn(a_isOn); + } + + /** Move the second control point if it was incorrectly set to the first one. + * + */ + private void correctControlPoint() { + if (!hasControlPoint1()) { + return; + } // if + + EControlPoint controlPoint = (EControlPoint) getControlPoint1(); + if (controlPoint.isFirst()) { + return; + } // if + + setControlPoint2(controlPoint); + setControlPoint1(null); + } + + public EContourPoint transpose(AffineTransform a_trans) { + EContourPoint retval = new EContourPoint(); + + retval.setPoint2d(EObject.createTransform(getPoint2d(), a_trans)); + retval.setOn(isOn()); + retval.setRounded(isRounded()); + + if (hasControlPoint1()) { + EControlPoint controlPoint = (EControlPoint) getControlPoint1(); + retval.setControlPoint1(controlPoint.transpose(a_trans)); + } // if + if (hasControlPoint2()) { + EControlPoint controlPoint = (EControlPoint) getControlPoint2(); + retval.setControlPoint2(controlPoint.transpose(a_trans)); + } // if + + int i; + XHint [] hints = getHint(); + for (i = 0; i < hints.length; i++) { + EHint hint = (EHint) hints[i]; + retval.addHint(hint.createTransform(a_trans)); + } // for i + + return retval; + } + + public void setNumber(int a_number) { + m_number = a_number; + } + + public void setOffset(double a_x, double a_y) { + m_xOffset = a_x; + m_yOffset = a_y; + } + + private AffineTransform buildOffsetTrans(AffineTransform a_trans) { + if (m_xOffset == 0 && m_yOffset == 0) { + return a_trans; + } // if + + AffineTransform retval = (AffineTransform) a_trans.clone(); + retval.translate(m_xOffset, m_yOffset); + + return retval; + } + public static final int k_defaultPixelSize = 16; + + public void display(Graphics2D g, AffineTransform a_trans) { + AffineTransform trans = buildOffsetTrans(a_trans); + + int ppem = k_defaultPixelSize; + Shape rect = toShape(trans, ppem); + g.setColor(GlyphColor.POINT); + if (isRounded()) { + g.setColor(GlyphColor.GRAY); + } // if + + if (isSelected()) { + g.setColor(GlyphColor.SELECTED); + } // if + + if (isOn()) + g.fill(rect); + else + g.draw(rect); + } + + + + public boolean isSelected() { + return EObject.getActives().isSelected(this); + } + + public void resetAdjusted() { + setAdjusted(getX(), getY()); + } + + public void roundAdjusted(int a_ppem) { + if (!isRounded()) { + return; + } // if + + setAdjusted(round(getX(), a_ppem), + round(getY(), a_ppem)); + } + + public void hintAdjusted(int a_ppem) { + if (!hasHintForPpem(a_ppem)) { + return; + } // if + + EHint hint = getHintForPpem(a_ppem); + setAdjusted(hint.getX(), hint.getY()); + } + + public void setAdjusted(double a_x, double a_y) { + m_adjusted = new Point2D.Double(a_x, a_y); + } + + public Point2D getAdjusted() { + return m_adjusted; + } + + public Shape toShape(AffineTransform a_trans, int a_ppem) { + return EObject.toShape(getPoint2d(), a_trans); + } + + public double getX() { + return getPoint2d().getX(); + } + + public double getY() { + return getPoint2d().getY(); + } + + public boolean isOn() { + return getType().equals(k_on); + } + + public boolean isRounded() { + return getRounded(); + } + + public void toggleRounded() { + if (hasHintForCurrentPpem()) { + return; + } // if + + setRounded(!isRounded()); + } + + public Point2D toPoint2D() { + return new Point2D.Double(getX(), getY()); + } + + public boolean hasHint() { + return (getHint().length > 0); + } + + public boolean hasHintForCurrentPpem() { + return hasHintForPpem(EContour.k_defaultPixelSize); + } + + public boolean hasHintForPpem(long a_ppem) { + return getHintForPpem(a_ppem) != null; + } + + public EPoint getHintIfPossible(long a_ppem) { + if (hasHintForPpem(a_ppem)) { + return getHintForPpem(a_ppem); + } // if + + return this; + } + + public EHint getCurrentHint() { + return getHintForPpem(EContour.k_defaultPixelSize); + } + + public EHint getHintForPpem(long a_ppem) { + int i; + XHint[] hints = getHint(); + for (i = 0; i < hints.length; i++) { + EHint hint = (EHint) hints[i]; + if (hint.getPpem() == a_ppem) { + return hint; + } // if + } // for i + + return null; + } + + public EHint addHint(int a_ppem) { + if (hasHintForPpem(a_ppem)) { + return getHintForPpem(a_ppem); + } // if + + EHint retval = new EHint(getX() + Engine.getEm() / a_ppem, getY(), a_ppem); + addHint(retval); + return retval; + } + + public GlyphObject add() { + return getParent().insertPoint(this); + } + + public void remove() { + getParent().removePoint(this); + } + + public PointAggregate getParent() { + if (rGetParentRNode() instanceof EControlPoint) { + EControlPoint controlPoint = (EControlPoint) rGetParentRNode(); + return controlPoint.getParent().getParent(); + } + + if (rGetParentRNode() instanceof PointAggregate) { + return (PointAggregate) rGetParentRNode(); + } // if + + return (PointAggregate) rGetParentRNode(); + } + + public XContourPoint cloneAt(Point2D a_point) { + EContourPoint retval = (EContourPoint) clone(); + Point2D delta = new Point2D.Double(a_point.getX() - this.getX(), a_point.getY() - this.getY()); + EObject.movePoint(retval, delta); + return retval; + } + + /** Moves point by the specified delta. A GlyphObject method. + * Delegates the implementation to the host since a point + * moves differently depending on the host. + * For example the first point hosted by a module invoke would + * always be (0, 0) so the invoke position would move instead. + */ + public void move(Point2D a_delta) { + PointAggregate parent = (PointAggregate) rGetParentRNode(); + parent.movePoint(this, a_delta); + } + + public void toggleOnCurve() { + if (isControlPoint()) { + return; + } // if + + if (getParent() instanceof EContour) { + EContour contour = (EContour) getParent(); + if (contour.isCubic()) { + toggleCubicControlPoint(); + return; + } // if + } // if + + setOn(!isOn()); + } + + public boolean isControlPoint() { + return (getParent() instanceof EContourPoint); + } + + private void toggleCubicControlPoint() { + if (hasControlPoint1() || hasControlPoint2()) { + setControlPoint1(null); + setControlPoint2(null); + } else { + setControlPoint1(new EControlPoint(true, getX() + 100, getY())); + setControlPoint2(new EControlPoint(false, getX() - 100, getY())); + } // if + } + + public boolean hasControlPoint1() { + return (getControlPoint1() != null); + } + + public boolean hasControlPoint2() { + return (getControlPoint2() != null); + } + + public void setOn(boolean a_isOnCurve) { + if (a_isOnCurve) { + setType(k_on); + } else { + setType(k_off); + } // if + } + + public boolean hitHint(Rectangle2D a_rect, AffineTransform a_trans) { + int ppem = EContour.k_defaultPixelSize; + if (!hasHintForPpem(ppem)) + return false; + + EHint hint = getHintForPpem(ppem); + + Shape hitArea = hint.toShape(a_trans, ppem); + if (!hitArea.intersects(a_rect)) { + return false; + } // if + + EObject.getActives().addActive(hint); + return true; + } + + public boolean hit(Rectangle2D a_rect, AffineTransform a_trans) { + return EObject.hit(this, a_rect, buildOffsetTrans(a_trans)); + } + + /** Round the value after converting to pixel coordinate system. + */ + private double round(double a_value, long a_ppem) { + double em = Engine.getEm(); + double funitInGrid = em / a_ppem; + + double pixelValue = a_value / funitInGrid; + return funitInGrid * roundSymetric(pixelValue); + } + + /** round symetrically about zero. + * Math.round(0.5) returns 1. Math.round(-0.5) returns 0, + * since it's Math.floor(a_value + -0.5). + * -0.5 should round to -1 if it's symetric about zero. + * @param a_value number to be rounded. + * @return round value. + */ + private int roundSymetric(double a_value) { + if (a_value < 0) { + int retval = (int) Math.round(-a_value); + return -retval; + } else { + return (int) Math.round(a_value); + } // if-else + } + + public void removeControlPoint(EControlPoint a_point) { + if (hasControlPoint1() && (getControlPoint1() == a_point)) { + setControlPoint1(null); + } // if + + if (hasControlPoint2() && (getControlPoint2() == a_point)) { + setControlPoint2(null); + } // if + } +} \ No newline at end of file diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EControlPoint.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EControlPoint.java new file mode 100644 index 000000000..70ed77625 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EControlPoint.java @@ -0,0 +1,244 @@ +/* + * $Id: EControlPoint.java,v 1.6 2004/12/27 04:56:02 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003-2004, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa.adapter; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Shape; +import java.awt.geom.AffineTransform; +import java.awt.geom.Line2D; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; + +import org.doubletype.ossa.GlyphColor; +import org.doubletype.ossa.xml.*; + +/** + * @author e.e + */ +public class EControlPoint extends XControlPoint implements GlyphObject, EPoint { + private static final String k_true = "true"; + + private double m_xOffset = 0; + private double m_yOffset = 0; + + public EControlPoint(boolean a_isFirst, double a_x, double a_y) { + setSmooth(true); + setFirst(a_isFirst); + setContourPoint(new EContourPoint(a_x, a_y, false)); + } + + /** + * + */ + public EControlPoint() { + super(); + } + + /** + * @param stack + */ + public EControlPoint(RStack stack) { + super(stack); + } + + public boolean isSelected() { + return EObject.getActives().isSelected(this); + } + + /** toggle smooth-ness + */ + public void convert() { + EContourPoint parent = getParent(); + boolean value = !getSmooth(); + parent.getControlPoint1().setSmooth(value); + parent.getControlPoint2().setSmooth(value); + move(new Point2D.Double(0, 0)); + } + + public boolean isFirst() { + return getFirst(); + } + + public boolean hit(Rectangle2D a_rect, AffineTransform a_trans) { + return EObject.hit(this, a_rect, buildOffsetTrans(a_trans)); + } + + public void setOffset(double a_x, double a_y) { + m_xOffset = a_x; + m_yOffset = a_y; + } + + private AffineTransform buildOffsetTrans(AffineTransform a_trans) { + if (m_xOffset == 0 && m_yOffset == 0) { + return a_trans; + } // if + + AffineTransform retval = (AffineTransform) a_trans.clone(); + retval.translate(m_xOffset, m_yOffset); + + return retval; + } + + public void remove() { + getParent().removeControlPoint(this); + } + + public EContourPoint getParent() { + return (EContourPoint) rGetParentRNode(); + } + + public Shape toShape(AffineTransform a_trans, int a_ppem) { + return EObject.toShape(getContourPoint().getPoint2d(), a_trans); + } + + public void move(Point2D a_delta) { + // if the parent is active, she will move this. + if (getParent().isSelected()) { + return; + } // if + + EObject.movePoint((EContourPoint) getContourPoint(), a_delta); + + if (isSmooth() && hasSibling()) { + smoothSibling(); + } // if + } + + public void rotateTo45() { + double theta = getTheta() + Math.PI / 8; + theta = Math.PI / 4 * Math.floor(theta / (Math.PI / 4)); + + rotateToTheta(theta); + if (isSmooth() && hasSibling()) { + smoothSibling(); + } // if + } + + private void smoothSibling() { + getSibling().rotateToTheta(getTheta() + Math.PI); + } + + private double getTheta() { + EContourPoint parent = getParent(); + return Math.atan2(getY() - parent.getY(), + getX() - parent.getX()); + } + + private void rotateToTheta(double a_theta) { + EContourPoint parent = getParent(); + double d = parent.toPoint2D().distance(toPoint2D()); + double x = parent.getX() + Math.cos(a_theta) * d; + double y = parent.getY() + Math.sin(a_theta) * d; + Point2D delta = new Point2D.Double(x - getX(), y - getY()); + EObject.movePoint((EContourPoint) getContourPoint(), delta); + } + + public Point2D toPoint2D() { + EContourPoint point = (EContourPoint) getContourPoint(); + return point.toPoint2D(); + } + + public boolean isSmooth() { + return getSmooth(); + } + + public boolean hasSibling() { + EContourPoint parent = getParent(); + if (parent.getControlPoint1() == this) { + return parent.hasControlPoint2(); + } else { + return parent.hasControlPoint1(); + } // if + } + + public EControlPoint getSibling() { + EContourPoint parent = getParent(); + if (parent.getControlPoint1() == this) { + return (EControlPoint) parent.getControlPoint2(); + } else { + return (EControlPoint) parent.getControlPoint1(); + } // if + } + + public void display(Graphics2D g, AffineTransform a_trans) { + AffineTransform trans = buildOffsetTrans(a_trans); + displayLine(g, trans); + + Shape rect = toShape(trans, EContour.k_defaultPixelSize); + g.setColor(GlyphColor.POINT); + if (isSelected()) { + g.setColor(GlyphColor.SELECTED); + } // if + + g.draw(rect); + } + + private void displayLine(Graphics2D g, AffineTransform a_trans) { + EContourPoint parent = getParent(); + Line2D line = new Line2D.Double(parent.getX(), + parent.getY(), + getX(), + getY()); + AffineTransform oldTrans = g.getTransform(); + + g.transform(a_trans); + g.setColor(Color.BLACK); + g.draw(line); + g.setTransform(oldTrans); + } + + public EControlPoint transpose(AffineTransform a_trans) { + EControlPoint retval = new EControlPoint(); + EContourPoint point = (EContourPoint) getContourPoint(); + retval.setContourPoint(point.transpose(a_trans)); + retval.setSmooth(getSmooth()); + + return retval; + } + + + public double getX() { + EContourPoint point = (EContourPoint) getContourPoint(); + return point.getX(); + } + + public double getY() { + EContourPoint point = (EContourPoint) getContourPoint(); + return point.getY(); + } +} + diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EGlyphFactory.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EGlyphFactory.java new file mode 100644 index 000000000..4575f06e8 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EGlyphFactory.java @@ -0,0 +1,109 @@ +/* + * $Id: EGlyphFactory.java,v 1.3 2004/11/10 01:49:49 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003-2004, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa.adapter; + +import org.doubletype.ossa.xml.*; + +/** + * @author e.e + */ +public class EGlyphFactory extends DefaultGlyphFactory { + public static IGlyphFactory s_factory = null; + + public static IGlyphFactory getFactory() { + if (s_factory == null) { + s_factory = new EGlyphFactory(); + } // if + + return s_factory; + } + + public EGlyphFactory() { + } + + public XModule createXModule() { + return new EModuleInvoke(); + } + + public Class getXModuleClass() { + return (EModuleInvoke.class); + } + + public XContour createXContour() { + return new EContour(); + } + + public Class getXContourClass() { + return (EContour.class); + } + + public XInclude createXInclude() { + return new EIncludeInvoke(); + } + + public Class getXIncludeClass() { + return (EIncludeInvoke.class); + } + + public XHint createXHint() { + return new EHint(); + } + + public Class getXHintClass() { + return (EHint.class); + } + + public XContourPoint createXContourPoint() { + return new EContourPoint(); + } + + public XContourPoint createXContourPoint(RStack a_stack) { + return new EContourPoint(a_stack); + } + + public Class getXContourPointClass() { + return (EContourPoint.class); + } + + public XControlPoint createXControlPoint() { + return new EControlPoint(); + } + + + public Class getXControlPointClass() { + return (EControlPoint.class); + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EHint.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EHint.java new file mode 100644 index 000000000..fedad33ca --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EHint.java @@ -0,0 +1,195 @@ +/* + * $Id: EHint.java,v 1.4 2004/12/27 04:56:03 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003-2004, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa.adapter; + +import java.awt.*; +import java.awt.geom.*; + +import org.doubletype.ossa.xml.*; +import org.doubletype.ossa.*; + +/** + * @author e.e + */ +public class EHint extends XHint implements GlyphObject, EPoint { + /** offset of this from the global coord. + * For contours, it will be 0. + * For module invoke, it will be pos.x. + * @see EContourPoint + */ + private double m_xOffset = 0; + private double m_yOffset = 0; + + public EHint() { + } + + public EHint(double a_x, double a_y, long a_ppem) { + XPoint2d point = new XPoint2d(); + point.setX(a_x); + point.setY(a_y); + + setPoint2d(point); + setPpem(a_ppem); + } + + public void setOffset(double a_x, double a_y) { + m_xOffset = a_x; + m_yOffset = a_y; + } + + private AffineTransform buildOffsetTrans(AffineTransform a_trans) { + if (m_xOffset == 0 && m_yOffset == 0) { + return a_trans; + } // if + + AffineTransform retval = (AffineTransform) a_trans.clone(); + retval.translate(m_xOffset, m_yOffset); + + return retval; + } + + public void display(Graphics2D g, AffineTransform a_trans) { + AffineTransform trans = buildOffsetTrans(a_trans); + + EContourPoint point = (EContourPoint) rGetParentRNode(); + + Shape rect = toShape(trans, EContour.k_defaultPixelSize); + Line2D line = new Line2D.Double(point.getX(), + point.getY(), + getX(), + getY()); + + AffineTransform oldTrans = g.getTransform(); + + g.transform(trans); + g.setColor(Color.BLACK); + g.draw(line); + g.setTransform(oldTrans); + + g.setColor(GlyphColor.HINT); + if (isSelected()) { + g.setColor(GlyphColor.SELECTED); + } // if + + if (point.isOn()) + g.fill(rect); + else + g.draw(rect); + } + + public boolean isSelected() { + return EObject.getActives().isSelected(this); + } + + public Shape toShape(AffineTransform a_trans, int a_ppem) { + return EObject.toShape(getPoint2d(), a_trans); + } + + public double getX() { + return getPoint2d().getX(); + } + + public double getY() { + return getPoint2d().getY(); + } + + public Point2D toPoint2D() { + return new Point2D.Double(getX(), getY()); + } + + /** + * @see org.doubletype.ossa.adapter.DObject#move(java.awt.geom.Point2D) + */ + public void move(Point2D a_delta) { + EObject.movePoint(getPoint2d(), a_delta); + + double gridWidth = ((double) Engine.getEm()) / getPpem(); + EContourPoint point = (EContourPoint) rGetParentRNode(); + + XPoint2d posHint = getPoint2d(); + XPoint2d posPoint = point.getPoint2d(); + double xDelta = posHint.getX() - posPoint.getX(); + double yDelta = posHint.getY() - posPoint.getY(); + + xDelta = correctDelta(xDelta, gridWidth); + yDelta = correctDelta(yDelta, gridWidth); + + posHint.setX(posPoint.getX() + xDelta); + posHint.setY(posPoint.getY() + yDelta); + } + + private double correctDelta(double a_delta, double a_width) { + double retval = a_delta; + + if (retval > a_width) { + retval = a_width; + } // if + + if (retval < -a_width) { + retval = -a_width; + } // if + + return retval; + } + + /** + * @see org.doubletype.ossa.adapter.DObject#remove() + */ + public void remove() { + getParent().removeHint(this); + } + + public EContourPoint getParent() { + return (EContourPoint) rGetParentRNode(); + } + + public PointAggregate getPointHost() { + return getParent().getParent(); + } + + public boolean hit(Rectangle2D a_rect, AffineTransform a_trans) { + return EObject.hit(this, a_rect, buildOffsetTrans(a_trans)); + } + + public EHint createTransform(AffineTransform a_trans) { + EHint retval = new EHint(); + + retval.setPpem(getPpem()); + retval.setPoint2d(EObject.createTransform(getPoint2d(), a_trans)); + + return retval; + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EIncludeInvoke.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EIncludeInvoke.java new file mode 100644 index 000000000..2210d11d0 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EIncludeInvoke.java @@ -0,0 +1,167 @@ +/* + * $Id: EIncludeInvoke.java,v 1.1 2004/09/04 21:54:07 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003-2004, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa.adapter; + +import java.awt.*; +import java.awt.geom.*; +import org.doubletype.ossa.xml.*; +import org.doubletype.ossa.*; +import org.doubletype.ossa.module.*; +import java.util.*; + +/** + * @author e.e + */ +public class EIncludeInvoke extends XInclude implements VarStackFrame, GlyphObject { + public static EIncludeInvoke create(String a_fileName) { + EIncludeInvoke retval = new EIncludeInvoke(); + retval.setHref(a_fileName); + retval.setInvoke(EObject.createInvoke(new Point2D.Double())); + + return retval; + } + + /** environment with invoke args. */ + private Hashtable m_augmented = new Hashtable<>(); + private VarStack m_stack = VarStack.getSingletonInstance(); + + public EIncludeInvoke() { + } + + public EIncludeInvoke(RStack a_stack) { + setup(a_stack); + } + + public void display(Graphics2D g, AffineTransform a_trans) { + g.setColor(GlyphColor.INCLUDE); + if (isSelected()) { + g.setColor(GlyphColor.SELECTED); + } // if + + g.draw(toShape(a_trans,EContour.k_defaultPixelSize)); + } + + public boolean isSelected() { + return EObject.getActives().isSelected(this); + } + + public Shape toShape(AffineTransform a_trans, int a_ppem) { + Shape retval; + + ModuleManager manager = ModuleManager.getSingletonInstance(); + GlyphFile file = manager.getGlyphFile(getHref()); + + XPoint2d pos = getInvoke().getInvokePos().getPoint2d(); + + AffineTransform trans = new AffineTransform(); + trans.setTransform(a_trans); + trans.translate(pos.getX(), pos.getY()); + + m_stack.push(this); + retval = file.toShape(trans); + m_stack.pop(); + + return retval; + } + + public GlyphModule getModule() { + ModuleManager manager = ModuleManager.getSingletonInstance(); + return manager.getGlyphFile(getHref()); + } + + // for var stack frame + public boolean hasVariable(String a_name) { + return m_augmented.containsKey(a_name); + } + + // for var stack frame. + public double getValue(String a_name) { + Double d = (Double) m_augmented.get(a_name); + return d.doubleValue(); + } + + // for var stack frame. + public void beforePush() { + getModule().beforePush(); + loadInvoke(getInvoke()); + } + + public void remove() { + XBody parent = (XBody) rGetParentRNode(); + parent.removeInclude(this); + } + + public void move(Point2D a_delta) { + XPoint2d point = getInvoke().getInvokePos().getPoint2d(); + EObject.movePoint(point, a_delta); + } + + /** + * loads invoke arguments into this module to build augmented environment. + * @param a_invoke + */ + private void loadInvoke(XInvoke a_invoke) { + copyVarsToAug(); + + int i; + XInvokeVarg [] vargs = a_invoke.getInvokeVarg(); + for (i = 0; i < vargs.length; i++) { + loadVarg(vargs[i]); + } // for i + } + + private void loadVarg(XInvokeVarg a_varg) { + String name = a_varg.getName(); + String src = a_varg.getSrc(); + GlyphModule module = getModule(); + + if (!module.hasVariable(name)) { + return; + } // if + + double value = m_stack.get(src); + m_augmented.put(name, new Double(value)); + } + + private void copyVarsToAug() { + m_augmented.clear(); + m_augmented.putAll(getModule().getVars()); + } + + public boolean hit(Rectangle2D a_rect, AffineTransform a_trans) { + return EObject.hit(this, a_rect, a_trans); + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EModuleInvoke.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EModuleInvoke.java new file mode 100644 index 000000000..25962b6c5 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EModuleInvoke.java @@ -0,0 +1,288 @@ +/* + * $Id: EModuleInvoke.java,v 1.4 2004/11/08 06:29:51 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003-2004, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa.adapter; + +import org.doubletype.ossa.*; +import org.doubletype.ossa.module.*; +import org.doubletype.ossa.xml.*; +import java.awt.geom.*; +import java.awt.*; +import java.util.*; + +/** + * @author e.e + */ +public class EModuleInvoke extends XModule implements VarStackFrame, GlyphObject, PointAggregate { + public static EModuleInvoke create() { + return createAt(new Point2D.Double(0, 254.0)); + } + + public static EModuleInvoke createAt(Point2D a_point) { + EModuleInvoke retval = new EModuleInvoke(); + + retval.setName(org.doubletype.ossa.module.Rectangle.class.getName()); + retval.setInvoke(EObject.createInvoke(a_point)); + + double x, y; + XContourPoint point; + + x = 0.0; + y = 0.0; + point = new EContourPoint(x, y, true); + retval.addContourPoint(point); + + + x += 426.0; + point = new EContourPoint(x, y, true); + retval.addContourPoint(point); + + y -= 254.0; + point = new EContourPoint(x, y, true); + retval.addContourPoint(point); + + x -= 426.0; + point = new EContourPoint(x, y, true); + retval.addContourPoint(point); + + return retval; + } + + + /** environment with invoke args. */ + private Hashtable m_augmented = new Hashtable<>(); + private VarStack m_stack = VarStack.getSingletonInstance(); + + // -------------------------------------------------------------- + + public EModuleInvoke() { + } + + public EModuleInvoke(RStack a_stack) { + setup(a_stack); + } + + // -------------------------------------------------------------- + + public void display(Graphics2D g, AffineTransform a_trans) { + if (isSelected()) { + g.setColor(GlyphColor.SELECTED); + } else { + g.setColor(GlyphColor.MODULE); + } // if + + g.draw(toShape(a_trans, EContour.k_defaultPixelSize)); + } + + public boolean isSelected() { + return EObject.getActives().isSelected(this); + } + + public Shape toShape(AffineTransform a_trans, int a_ppem) { + EContour contour = toContour(a_trans); + return contour.toShape(new AffineTransform(), a_ppem); + } + + // -------------------------------------------------------------- + + public EContour toContour(AffineTransform a_trans) { + EContour retval; + + GlyphModule module = getModule(); + + m_stack.push(this); + EContour untransContour = module.toContour(this); + m_stack.pop(); + + XPoint2d pos = getInvoke().getInvokePos().getPoint2d(); + AffineTransform trans = (AffineTransform) a_trans.clone(); + trans.translate(pos.getX(), pos.getY()); + + retval = untransContour.transpose(trans); + + return retval; + } + + public GlyphModule getModule() { + return getModuleForName(getName()); + } + + private GlyphModule getModuleForName(String a_name) { + GlyphModule retval = null; + + try { + ModuleManager manager = ModuleManager.getSingletonInstance(); + retval = manager.getModule(a_name); + } catch (Exception e) { + e.printStackTrace(); + } // try-catch + + return retval; + } + + public void remove() { + XBody parent = (XBody) rGetParentRNode(); + parent.removeModule(this); + } + + public void move(Point2D a_delta) { + XPoint2d point = getInvoke().getInvokePos().getPoint2d(); + EObject.movePoint(point, a_delta); + } + + // PointAggregate + public void removePoint(EContourPoint a_point) { + boolean isFirst = (a_point == getContourPoint(0)); + removeContourPoint(a_point); + + GlyphModule module = getModuleForName(getName()); + + if (getContourPoint().length < module.getMinimumPointCount()) + { + remove(); + return; + } // if + + if (!isFirst) { + return; + } // if + + EContourPoint newFirst = (EContourPoint) getContourPoint(0); + Point2D pos = newFirst.toPoint2D(); + Point2D delta = new Point2D.Double(-pos.getX(), -pos.getY()); + moveModulePoints(delta); + move(pos); + } + + public void moveModulePoints(Point2D a_delta) { + XContourPoint [] points = getContourPoint(); + + int i; + for (i = 0; i < points.length; i++) { + EContourPoint point = (EContourPoint) points[i]; + EObject.movePoint(point, a_delta); + } // for i + } + + // for var stack frame + public boolean hasVariable(String a_name) { + return m_augmented.containsKey(a_name); + } + + // for var stack frame. + public double getValue(String a_name) { + Double d = (Double) m_augmented.get(a_name); + return d.doubleValue(); + } + + // for var stack frame. + public void beforePush() { + loadInvoke(getInvoke()); + } + + /** + * loads invoke arguments into this module to build augmented environment. + * @param a_invoke + */ + private void loadInvoke(XInvoke a_invoke) { + copyVarsToAug(); + + // load varg + int i; + XInvokeVarg [] vargs = a_invoke.getInvokeVarg(); + for (i = 0; i < vargs.length; i++) { + loadVarg(vargs[i]); + } // for i + } + + private void loadVarg(XInvokeVarg a_varg) { + String name = a_varg.getName(); + String src = a_varg.getSrc(); + GlyphModule module = getModule(); + + if (!module.hasVariable(name)) { + System.out.println(name + " does not exist in " + + module.toString()); + + return; + } // if + + double value = m_stack.get(src); + m_augmented.put(name, new Double(value)); + } + + private void copyVarsToAug() { + m_augmented.clear(); + m_augmented.putAll(getModule().getVars()); + } + + public void movePoint(EContourPoint a_point, Point2D a_delta) { + EObject.movePoint(a_point, a_delta); + + if (a_point != getContourPoint(0)) { + return; + } // if + + Point2D negative = new Point2D.Double(-a_delta.getX(), -a_delta.getY()); + moveModulePoints(negative); + move(a_delta); + } + + public GlyphObject insertPoint(EContourPoint a_point) { + int i; + int len = getContourPoint().length; + + for (i = 0; i < len; i++) { + if (getContourPoint(i) == a_point) { + break; + } // if + } // for + + EContourPoint nextPoint; + nextPoint = (EContourPoint) getContourPoint((i + 1) % len); + + double x = (a_point.getX() + nextPoint.getX()) / 2; + double y = (a_point.getY() + nextPoint.getY()) / 2; + + EContourPoint retval = new EContourPoint(x, y, true); + addContourPoint(i + 1, retval); + + return retval; + } + + public boolean hit(Rectangle2D a_rect, AffineTransform a_trans) { + return EObject.hit(this, a_rect, a_trans); + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EObject.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EObject.java new file mode 100644 index 000000000..5f5f7e0c2 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EObject.java @@ -0,0 +1,158 @@ +/* + * $Id: EObject.java,v 1.2 2004/11/08 06:29:51 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003-2004, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa.adapter; + +import java.awt.geom.*; +import java.awt.*; + +import org.doubletype.ossa.*; +import org.doubletype.ossa.truetype.TTPixelSize; +import org.doubletype.ossa.xml.*; + +/** Decorator class of xml objects. + * @author e.e + */ +public abstract class EObject { + public static final String k_on = "on"; + public static final String k_off = "off"; + + private static ActiveList s_actives = null; + + + static ActiveList getActives() { + if (s_actives == null) { + s_actives = ActiveList.getSingletonInstance(); + } // if + + return s_actives; + } + + static Shape toShape(XPoint2d a_point, AffineTransform a_trans) { + + double ratio= EContour.k_defaultPixelSize/TTPixelSize.getEm(); + + double x = a_point.getX(); + double y = a_point.getY(); + double e = 3 / ratio; + Point2D source, dest; + source = new Point2D.Double(x, y); + dest = new Point2D.Double(); + dest = a_trans.transform(source, dest); + x = dest.getX(); + y = dest.getY(); + + return new Rectangle2D.Double(x - e, y - e, 2 * e + 1, 2 * e + 1); + } + + static void movePoint(XPoint2d a_point, Point2D a_delta) { + double x = a_point.getX() + a_delta.getX(); + double y = a_point.getY() + a_delta.getY(); + + a_point.setX(x); + a_point.setY(y); + } + + /** + * move the point and hint + * @param a_point + * @param a_delta + */ + public static void movePoint(EContourPoint a_point, Point2D a_delta) { + movePoint(a_point.getPoint2d(), a_delta); + + XHint [] hints = a_point.getHint(); + for (int i = 0; i < hints.length; i++) { + XHint hint = hints[i]; + movePoint(hint.getPoint2d(), a_delta); + } // for i + + if (a_point.hasControlPoint1()) { + EContourPoint point = (EContourPoint) a_point.getControlPoint1().getContourPoint(); + movePoint(point, a_delta); + } // if + if (a_point.hasControlPoint2()) { + EContourPoint point = (EContourPoint) a_point.getControlPoint2().getContourPoint(); + movePoint(point, a_delta); + } // if + } + + public static boolean hit(GlyphObject a_object, Rectangle2D a_rect, AffineTransform a_trans) { + int ppem = EContour.k_defaultPixelSize; + Shape hitArea = a_object.toShape(a_trans, ppem); + if (!hitArea.intersects(a_rect)) { + return false; + } // if + + EObject.getActives().addActive(a_object); + return true; + } + + public static XInvoke createInvoke(Point2D a_point) { + XInvoke retval = new XInvoke(); + retval.setInvokePos(createInvokePos(a_point.getX(), a_point.getY())); + return retval; + } + + public static XPoint2d createTransform(XPoint2d a_point, AffineTransform a_trans) { + XPoint2d retval = new XPoint2d(); + + double x = a_point.getX(); + double y = a_point.getY(); + Point2D source = new Point2D.Double(x, y); + Point2D dest = new Point2D.Double(); + a_trans.transform(source, dest); + + retval.setX(dest.getX()); + retval.setY(dest.getY()); + + return retval; + } + + private static XInvokePos createInvokePos(double a_x, double a_y) { + XInvokePos retval = new XInvokePos(); + retval.setPoint2d(createPoint2d(a_x, a_y)); + return retval; + } + + + private static XPoint2d createPoint2d(double a_x, double a_y) { + XPoint2d retval = new XPoint2d(); + retval.setX(a_x); + retval.setY(a_y); + return retval; + } + +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EPoint.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EPoint.java new file mode 100644 index 000000000..4a59fb58a --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/EPoint.java @@ -0,0 +1,44 @@ +/* + * $Id: EPoint.java,v 1.1 2004/12/27 04:56:02 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2004, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa.adapter; + +/** + * @author e.e + */ +public interface EPoint { + double getX(); + double getY(); +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/Emulator.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/Emulator.java new file mode 100644 index 000000000..c3b695969 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/Emulator.java @@ -0,0 +1,360 @@ +/* + * $Id: Emulator.java,v 1.6 2004/12/27 04:56:02 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2004, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa.adapter; + +import java.awt.*; +import java.awt.geom.*; +import java.util.*; +import org.doubletype.ossa.xml.*; + +/** Emulator emulates font engine. + * @author e.e + */ +public class Emulator { + private static Emulator s_instance = null; + + // singleton pattern + public static Emulator getInstance() { + if (s_instance == null) { + s_instance = new Emulator(); + } // if + + return s_instance; + } + + private Emulator() { + super(); + } + + public Shape createShape(EContour a_contour, int a_ppem) { + if (a_contour.isCubic()) { + // return createBezierCurve(a_contour); + EContour contour = a_contour.toQuadratic(); + return createShape(contour, a_ppem); + } // if + + return concretePointsToShape(createConcretePoints( + createAdjustedPoints(a_contour, a_ppem))); + } + + private Shape createBezierCurve(EContour a_contour) { + GeneralPath retval = new GeneralPath(); + XContourPoint [] points = a_contour.getContourPoint(); + + if (points.length < 2) { + return retval; + } // if + + EContourPoint startPoint = (EContourPoint) points[points.length - 1]; + retval.moveTo((float) startPoint.getX(), (float) startPoint.getY()); + + for (int i = 0; i < points.length; i++) { + EContourPoint toPoint = (EContourPoint) points[i]; + EControlPoint controlPoint1 = (EControlPoint) startPoint.getControlPoint2(); + EControlPoint controlPoint2 = (EControlPoint) toPoint.getControlPoint1(); + + // line segment + if ((controlPoint1 == null) && (controlPoint2 == null)) { + retval.lineTo((float) toPoint.getX(), (float) toPoint.getY()); + + } // if + + if ((controlPoint1 != null) && (controlPoint2 == null)) { + retval.curveTo((float) controlPoint1.getX(), (float) controlPoint1.getY(), + (float) toPoint.getX(), (float) toPoint.getY(), + (float) toPoint.getX(), (float) toPoint.getY()); + } // if + + if ((controlPoint1 == null) && (controlPoint2 != null)) { + retval.curveTo((float) startPoint.getX(), (float) startPoint.getY(), + (float) controlPoint2.getX(), (float) controlPoint2.getY(), + (float) toPoint.getX(), (float) toPoint.getY()); + } // if + + if ((controlPoint1 != null) && (controlPoint2 != null)) { + retval.curveTo((float) controlPoint1.getX(), (float) controlPoint1.getY(), + (float) controlPoint2.getX(), (float) controlPoint2.getY(), + (float) toPoint.getX(), (float) toPoint.getY()); + } // if + + startPoint = toPoint; + } // for + + return retval; + } + + private Shape concretePointsToShape(java.util.List a_listOfPoints) { + GeneralPath retval = new GeneralPath(); + EContourPoint p; + + if (a_listOfPoints.size() < 3) + return retval; + + p = (EContourPoint) a_listOfPoints.get(0); + retval.moveTo((float) p.getX(), (float) p.getY()); + + int i = 0; + while (i < a_listOfPoints.size() - 1) { + i++; + EContourPoint nextPoint = (EContourPoint) a_listOfPoints.get(i); + + if (nextPoint.isOn()) { + retval.lineTo((float) nextPoint.getX(), (float) nextPoint.getY()); + } else { + EContourPoint controlPoint = nextPoint; + i++; + EContourPoint toPoint = (EContourPoint) a_listOfPoints.get(i); + + retval.quadTo((float) controlPoint.getX(), + (float) controlPoint.getY(), + (float) toPoint.getX(), (float) toPoint.getY()); + } // if-else + } // for + + return retval; + } + + private java.util.List createConcretePoints(java.util.List a_points) { + java.util.List retval = new ArrayList<>(); + + if (a_points.size() < 3) + return retval; + + EContourPoint lastPoint = (EContourPoint) a_points.get(a_points.size() - 1); + for (int i = 0; i < a_points.size(); i++) { + EContourPoint point = (EContourPoint) a_points.get(i); + + if (!point.isOn() && !lastPoint.isOn()) { + double xMidpoint = (point.getX() + lastPoint.getX()) / 2; + double yMidpoint = (point.getY() + lastPoint.getY()) / 2; + retval.add(new EContourPoint(xMidpoint, yMidpoint, true)); + } // if + + retval.add(new EContourPoint(point.getX(), point.getY(), point.isOn())); + lastPoint = point; + } // for i + + // all contours should start with on-curve point + // move off-curve point to the end if a contour starts with one. + EContourPoint point = (EContourPoint) retval.get(0); + if (!point.isOn()) { + retval.remove(0); + retval.add(point); + } // if + + point = (EContourPoint) retval.get(0); + retval.add(point); + + return retval; + } + + private java.util.List createAdjustedPoints(EContour a_contour, int a_ppem) { + java.util.List retval = new ArrayList<>(); + + XContourPoint [] points = a_contour.getContourPoint(); + if (points.length < 3) { + return retval; + } // if + + boolean isRounded = false; + for (int i = 0; i < points.length; i++) { + EContourPoint point = (EContourPoint) points[i]; + point.resetAdjusted(); + + if (point.isRounded()) { + isRounded = true; + point.roundAdjusted(a_ppem); + } // if + + retval.add(point); + } // for i + + if (isRounded) { + interpolate(retval, true); + interpolate(retval, false); + } // if + + for (int i = 0; i < retval.size(); i++) { + EContourPoint point = (EContourPoint) retval.get(i); + if (point.hasHintForPpem(a_ppem)) { + point.hintAdjusted(a_ppem); + } // if + } // for i + + return promoteAdjustedToMain(retval); + } + + private java.util.List promoteAdjustedToMain(java.util.List a_points) { + java.util.List retval = new ArrayList<>(); + for (int i = 0; i < a_points.size(); i++) { + EContourPoint original = (EContourPoint) a_points.get(i); + EContourPoint adjusted = new EContourPoint(original.getAdjusted().getX(), + original.getAdjusted().getY(), + original.isOn()); + + retval.add(adjusted); + } // for i + + return retval; + } + + private void interpolate(java.util.List a_points, boolean a_isX) { + Collection sorted = sortPoints(a_points, a_isX); + + Iterator itr = sorted.iterator(); + + EContourPoint first = (EContourPoint) itr.next(); + if (!first.isRounded()) { + shiftPoint(first, a_points, a_isX); + } // if + + EContourPoint second = (EContourPoint) itr.next(); + EContourPoint third = null; + while (itr.hasNext()) { + third = (EContourPoint) itr.next(); + + if (!second.isRounded()) { + if (first.isRounded() + && third.isRounded()) { + interpolate(first, second, third, a_isX); + } else { + shiftPoint(second, a_points, a_isX); + } // if-else + } // if + + first = second; + second = third; + } // while + + EContourPoint last = third; + if (!last.isRounded()) { + shiftPoint(last, a_points, a_isX); + } // if + } + + private Collection sortPoints(java.util.List a_points, boolean a_isX) { + Map sorted = new TreeMap<>(); + + for (int i = 0; i < a_points.size(); i++) { + EContourPoint original = (EContourPoint) a_points.get(i); + Double value = new Double(getPointValue(original, a_isX)); + + while (sorted.containsKey(value)) { + value = new Double(value.doubleValue() + 0.01); + } // while + sorted.put(value, original); + } // for i + + return sorted.values(); + } + + private void interpolate(EContourPoint a_first, EContourPoint a_second, EContourPoint a_third, boolean a_isX) { + double firstValue = getPointValue(a_first, a_isX); + double secondValue = getPointValue(a_second, a_isX); + double thirdValue = getPointValue(a_third, a_isX); + double adjustedFirst = getAdjustedValue(a_first, a_isX); + double adjustedThird = getAdjustedValue(a_third, a_isX); + + double ratio = (secondValue - firstValue) / (thirdValue - firstValue); + + secondValue = adjustedFirst + ratio * (adjustedThird - adjustedFirst); + setAdjusted(a_second, secondValue, a_isX); + } + + private void shiftPoint(EContourPoint a_point, java.util.List a_points, boolean a_isX) { + EContourPoint closest = closestTouchedPoint(a_point, a_points); + if (closest == null) { + return; + } // if + + double delta = getAdjustedValue(closest, a_isX) - getPointValue(closest, a_isX); + double value = getPointValue(a_point, a_isX) + delta; + setAdjusted(a_point, value, a_isX); + } + + private void setAdjusted(EContourPoint a_point, double a_value, boolean a_isX) { + double x = a_point.getX(); + double y = a_point.getY(); + + if (a_isX) { + x = a_value; + } else { + y = a_value; + } // if-else + + a_point.setAdjusted(x, y); + } + + private double getPointValue(EContourPoint a_point, boolean a_isX) { + if (a_isX) { + return a_point.getX(); + } else { + return a_point.getY(); + } // if-else + } + + private double getAdjustedValue(EContourPoint a_point, boolean a_isX) { + if (a_isX) { + return a_point.getAdjusted().getX(); + } else { + return a_point.getAdjusted().getY(); + } // if-else + } + + private EContourPoint closestTouchedPoint(EContourPoint a_point, java.util.List a_points) { + EContourPoint retval = null; + double min = Double.MAX_VALUE; + for (int i = 0; i < a_points.size(); i++) { + EContourPoint target = (EContourPoint) a_points.get(i); + if (target == a_point) { + continue; + } // if + + if (!target.isRounded()) { + continue; + } // if + + double d = a_point.toPoint2D().distance(target.toPoint2D()); + if (d < min) { + min = d; + retval = target; + } // if + + } // for i + + return retval; + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/GlyphObject.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/GlyphObject.java new file mode 100644 index 000000000..2a7e70724 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/GlyphObject.java @@ -0,0 +1,51 @@ +/* + * $Id: GlyphObject.java,v 1.1 2004/09/04 21:54:06 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003-2004, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa.adapter; + +import java.awt.*; +import java.awt.geom.*; + +/** + * @author e.e + */ +public interface GlyphObject { + void move(Point2D a_delta); + void remove(); + Shape toShape(AffineTransform a_trans, int a_ppem); + boolean isSelected(); + void display(Graphics2D g, AffineTransform a_trans); + boolean hit(Rectangle2D a_rect, AffineTransform a_trans); +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/PointAggregate.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/PointAggregate.java new file mode 100644 index 000000000..b1b6a5003 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/PointAggregate.java @@ -0,0 +1,49 @@ +/* + * $Id: PointAggregate.java,v 1.2 2004/09/18 07:30:44 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2004, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa.adapter; + +import java.awt.geom.*; +import org.doubletype.ossa.xml.*; + +/** + * @author e.e + */ +public interface PointAggregate { + void removePoint(EContourPoint a_point); + void movePoint(EContourPoint a_point, Point2D a_delta); + GlyphObject insertPoint(EContourPoint a_point); + XContourPoint[] getContourPoint(); +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/QuadraticSegment.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/QuadraticSegment.java new file mode 100644 index 000000000..758a160cd --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/adapter/QuadraticSegment.java @@ -0,0 +1,188 @@ +/* + * $Id: QuadraticSegment.java,v 1.1 2004/12/15 11:54:18 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2004, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa.adapter; + +import java.util.*; + +import org.doubletype.ossa.xml.XContourPoint; + +/** + * @author e.e + */ +public class QuadraticSegment { + public static final int LINE = 0; + public static final int CURVE = 1; + + /** + * converts quadratic contour into a list of quadratic segments. + * @param a_contour + * @return + */ + public static ArrayList toSegments(EContour a_contour) { + ArrayList retval = new ArrayList<>(); + + ArrayList points = toConcreatePoints(a_contour); + if (points.size() < 3) { + return retval; + } // if + + for (int i = 0; i < points.size() - 1; i++) { + EContourPoint startPoint = (EContourPoint) points.get(i); + EContourPoint nextPoint = (EContourPoint) points.get(i + 1); + + // if this is a line segment + if (nextPoint.isOn()) { + retval.add(new QuadraticSegment(startPoint, null, nextPoint)); + } else { + EContourPoint offCurvePoint = nextPoint; + i++; + nextPoint = (EContourPoint) points.get(i + 1); + retval.add(new QuadraticSegment(startPoint, offCurvePoint, nextPoint)); + } // if-else + } // for i + + return retval; + } + + /** + * converts a list of quadratic segments into a quadratic contour. + * @param a_segments + * @return + */ + public static EContour toContour(ArrayList a_segments) { + EContour retval = new EContour(); + retval.setType(EContour.k_quadratic); + + for (QuadraticSegment segment: a_segments) { + EContourPoint startPoint = (EContourPoint) segment.m_startPoint.clone(); + startPoint.setControlPoint1(null); + startPoint.setControlPoint2(null); + + if (segment.m_type == LINE) { + retval.addContourPoint(startPoint); + + } else { + retval.addContourPoint(startPoint); + retval.addContourPoint(segment.m_offCurvePoint); + } + } // for i + + return retval; + } + + /** + * converts quadratic contour to concreate points by inserting + * on-curve point between off-curve points. + * @param a_contour + * @return + */ + private static ArrayList toConcreatePoints(EContour a_contour) { + ArrayList retval = new ArrayList<>(); + + XContourPoint [] points = a_contour.getContourPoint(); + if (points.length < 3) + return retval; + + EContourPoint fromPoint = (EContourPoint) points[points.length - 1]; + for (XContourPoint point: points) { + EContourPoint toPoint = (EContourPoint) point; + if (!toPoint.isOn() && !fromPoint.isOn()) { + double xMidpoint = (toPoint.getX() + fromPoint.getX()) / 2; + double yMidpoint = (toPoint.getY() + fromPoint.getY()) / 2; + retval.add(new EContourPoint(xMidpoint, yMidpoint, true)); + } // if + + retval.add(toPoint); + fromPoint = toPoint; + } // for i + + // all contours should start with on-curve point + // move off-curve point to the end if a contour starts with one. + EContourPoint firstPoint = (EContourPoint) retval.get(0); + if (!firstPoint.isOn()) { + retval.remove(0); + retval.add(firstPoint); + } // if + + retval.add(retval.get(0)); + + return retval; + } + + private EContourPoint m_startPoint; + private EContourPoint m_offCurvePoint; + private EContourPoint m_endPoint; + + private int m_type = LINE; + + /** + * + */ + public QuadraticSegment(EContourPoint a_startPoint, EContourPoint a_offCurvePoint, + EContourPoint a_endPoint) { + m_startPoint = a_startPoint; + m_offCurvePoint = a_offCurvePoint; + m_endPoint = a_endPoint; + + if (m_offCurvePoint != null) { + m_type = CURVE; + } // if + } + + /** + * Convert quadratic segment to cubic. + * @param a_segment + * @return + */ + public CubicSegment toCubicSegment() { + // if the segment is a line + if (m_type == LINE) { + return new CubicSegment(m_startPoint, m_endPoint); + } // if + + double x, y; + x = m_startPoint.getX() + 2.0 / 3.0 * (m_offCurvePoint.getX() - m_startPoint.getX()); + y = m_startPoint.getY() + 2.0 / 3.0 * (m_offCurvePoint.getY() - m_startPoint.getY()); + EContourPoint controlPoint1 = new EContourPoint(x, y, false); + + x = m_offCurvePoint.getX() + 1.0 / 3.0 * (m_endPoint.getX() - m_offCurvePoint.getX()); + y = m_offCurvePoint.getY() + 1.0 / 3.0 * (m_endPoint.getY() - m_offCurvePoint.getY()); + EContourPoint controlPoint2 = new EContourPoint(x, y, false); + + return new CubicSegment(m_startPoint, controlPoint1, controlPoint2, m_endPoint); + } + +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/module/GlyphFile.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/module/GlyphFile.java new file mode 100644 index 000000000..fd57a24d3 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/module/GlyphFile.java @@ -0,0 +1,1141 @@ + /* + * $Copyright: copyright (c) 2003-2008, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa.module; + +import org.doubletype.ossa.*; +import org.doubletype.ossa.xml.*; +import org.doubletype.ossa.adapter.*; +import org.doubletype.ossa.truetype.*; + +import java.io.*; +import java.awt.*; +import java.awt.geom.*; + +import javax.xml.transform.*; +import javax.xml.transform.stream.*; +import javax.xml.transform.dom.*; +import java.net.*; +import java.util.*; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.w3c.dom.*; +import javax.xml.parsers.*; +import org.xml.sax.*; + +/** + * @author e.e + */ +public class GlyphFile extends GlyphModule { + protected static String s_emptyFileName = "empty.glyph"; + private static final String k_dotGlyph = ".glyph"; + private static Transformer s_transformer = null; + + static { + GlyphFactory.setFactory(EGlyphFactory.getFactory()); + } + + public static File createFileName(File a_dir, String a_name) { + return new File(a_dir, a_name + k_dotGlyph); + } + + /** + * http://www.atmarkit.co.jp/fxml/rensai2/xmltool04/02.html + * @return + */ + private static Transformer getTransformer() { + if (s_transformer == null) { + TransformerFactory transFactory + = TransformerFactory.newInstance(); + try { + s_transformer = transFactory.newTransformer(); + } + catch (TransformerConfigurationException e) { + } + + s_transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); + s_transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + } // if + + return s_transformer; + } + + private static XStartGlyphElement loadGlyphElement(URL a_url) { + IGlyphFactory factory = GlyphFactory.getFactory(); + + XStartGlyphElement retval = null; + + try { + retval = factory.createXStartGlyphElement(a_url); + } catch( SAXException | ParserConfigurationException | IOException e) { + e.printStackTrace(); + } + + return retval; + } + + private static XStartGlyphElement loadGlyphElement(InputStream a_in) { + IGlyphFactory factory = GlyphFactory.getFactory(); + XStartGlyphElement retval = null; + + try { + retval = factory.createXStartGlyphElement(a_in); + } catch( SAXException | ParserConfigurationException | IOException e) { + e.printStackTrace(); + } + + return retval; + } + // -------------------------------------------------------------- + + protected XStartGlyphElement m_glyph; + protected File m_fileName; + protected long m_modifiedTime = 0; + protected long m_savedTime = 0; + protected HistoryList m_history; + + private final int k_halfWidth = 512; + private final int k_fullWidth = 1024; + private String m_selectedNodeName = ""; + private boolean m_isMoving = false; + private PointAggregate m_pointHost; + + + // -------------------------------------------------------------- + + /** + * creates new file + */ + public GlyphFile(File a_dir, String a_name, long a_unicode) throws FileNotFoundException { + super(); + + m_fileName = createFileName(a_dir, a_name); + + init(getClass().getResource(s_emptyFileName)); + setGlyphTitle(a_name); + setUnicode(Long.toHexString(a_unicode)); + + /*int eastAsianWidth = UCharacter.getIntPropertyValue( + (int) a_unicode, + 0x1004); //UProperty.EAST_ASIAN_WIDTH); + */ + int eastAsianWidth = 5; //?? + if (eastAsianWidth == 5 || eastAsianWidth == 1) { + setAdvanceWidth(k_fullWidth); + } // if + + saveGlyphFile(); + } + + /** + * creates new file + * @param a_dir parent dir + * @param a_name glyph name + */ + public GlyphFile(File a_dir, String a_name) throws FileNotFoundException { + super(); + init(getClass().getResource(s_emptyFileName)); + setGlyphTitle(a_name); + m_fileName = createFileName(a_dir, a_name); + saveGlyphFile(); + } + + /** + * opens existing file + * @param a_file + */ + public GlyphFile(File a_file) { + super(); + + m_fileName = a_file; + + URL url = null; + + try { + url = a_file.toURI().toURL(); + } catch(MalformedURLException e) { + e.printStackTrace(); + } + + init(url); + } + + protected GlyphFile(URL a_url) { + super(); + init(a_url); + } + + private void init(URL a_url) { + m_glyph = loadGlyphElement(a_url); + ModuleManager.getSingletonInstance().clear(); + + //m_display = Engine.getSingletonInstance().getDisplay(); + m_history = new HistoryList(this); + + m_history.record("loadFile"); + m_savedTime = m_modifiedTime; + } + + /** + * initialize .notdef + */ + public void initNotDef(int a_advanceWidth) throws FileNotFoundException { + setAdvanceWidth(a_advanceWidth); + + EContour contour = new EContour(); + contour.setType(EContour.k_cubic); + contour.addContourPoint(new EContourPoint(0.0, 0.0, true)); + contour.addContourPoint(new EContourPoint(438.0, 0.0, true)); + contour.addContourPoint(new EContourPoint(438.0, 683.0, true)); + contour.addContourPoint(new EContourPoint(0.0, 683.0, true)); + addContour(contour); + + contour = new EContour(); + contour.setType(EContour.k_cubic); + contour.addContourPoint(new EContourPoint(365.0, 73.0, true)); + contour.addContourPoint(new EContourPoint(73.0, 73.0, true)); + contour.addContourPoint(new EContourPoint(73.0, 610.0, true)); + contour.addContourPoint(new EContourPoint(365.0, 610.0, true)); + addContour(contour); + + saveGlyphFile(); + } + + public void initNullGlyph() throws FileNotFoundException { + setAdvanceWidth(0); + saveGlyphFile(); + } + + public void initSpace(int a_advanceWidth) throws FileNotFoundException { + setAdvanceWidth(a_advanceWidth); + saveGlyphFile(); + } + + public void beforePush() { + loadVar(); + } + + public void undo() { + m_history.undo(); + } + + public void redo() { + m_history.redo(); + } + + public void restore(Memento a_memento) { + m_glyph = loadGlyphElement(a_memento.getData()); + ModuleManager.getSingletonInstance().clear(); + } + + // -------------------------------------------------------------- + + public XStartGlyphElement getGlyph() { + return m_glyph; + } + + // -------------------------------------------------------------- + + public void saveGlyphFile() throws FileNotFoundException { + saveGlyphFile(m_fileName); + } + + protected void saveGlyphFile(File a_file) throws FileNotFoundException { + FileOutputStream output = new FileOutputStream(a_file); + saveGlyphFile(output); + try { + output.close(); //JPEXS + } catch (IOException ex) { + Logger.getLogger(GlyphFile.class.getName()).log(Level.SEVERE, null, ex); + } + } + + public void saveGlyphFile(OutputStream a_output) { + try { + Transformer transformer = getTransformer(); + Document document = m_glyph.makeDocument(); + DOMSource source = new DOMSource(document); + StreamResult result = new StreamResult(a_output); + transformer.transform(source, result); + } catch (ParserConfigurationException | TransformerException e) { + e.printStackTrace(); + } + + m_savedTime = System.currentTimeMillis(); + m_modifiedTime = m_savedTime; + } + + public Memento createMemento(String a_description) { + m_modifiedTime = System.currentTimeMillis(); + byte [] bytes = m_glyph.makeTextDocument().getBytes(); + return new Memento(a_description, bytes); + } + + public boolean hasUnsavedChange() { + return (m_savedTime != m_modifiedTime); + } + + public void setAuthor(String a_value) { + m_glyph.getHead().setAuthor(a_value); + m_history.record("setAuthor"); + } + + public String getAuthor() { + return m_glyph.getHead().getAuthor(); + } + + public void setCopyrightYear(String a_value) { + m_glyph.getHead().setCopyright(a_value); + m_history.record("setCopyrightYear"); + } + + public String getCopyrightYear() { + return m_glyph.getHead().getCopyright(); + } + + public void setAdvanceWidth(int a_width) { + m_glyph.getHead().setAdvanceWidth(a_width); + m_history.record("setAdvanceWidth"); + } + + public int getAdvanceWidth() { + if (!m_glyph.getHead().checkAdvanceWidth()) { + setAdvanceWidth(k_halfWidth); + } // if + + return (int) m_glyph.getHead().getAdvanceWidth(); + } + + public Iterator createIterator() { + return new GlyphIterator(this); + } + + + // -------------------------------------------------------------- + + public void display(Graphics2D g, AffineTransform a_trans) + { + Iterator i = createIterator(); + while (i.hasNext()) { + GlyphObject object = (GlyphObject) i.next(); + object.display(g, a_trans); + } // while + } + + // -------------------------------------------------------------- + + public static final int k_defaultPixelSize = 16; //PPM + + /** converts this glyph into Shape. + * It could be called for root's preview mode or by include invoke. + * Pushing either this GlyphFile or DIncludeInvoke should be + * handled before this. + */ + public Shape toShape(AffineTransform a_trans) { + + + int ppem = k_defaultPixelSize; + + GeneralPath retval = new GeneralPath(); + Iterator i = createIterator(); + while (i.hasNext()) { + GlyphObject object = (GlyphObject) i.next(); + + if (object instanceof EContourPoint + || object instanceof EHint) { + continue; + } // if + + retval.append(object.toShape(a_trans, ppem), false); + } // if + + return retval; + } + + // -------------------------------------------------------------- + + /** + * Generates array of XContour from local contours and modules. + * Used for TTF building. + */ + private XContour [] toContours() { + XContour [] retval; + ArrayList list = new ArrayList<>(); + XContour [] contours = m_glyph.getBody().getContour(); + for (int i = 0; i < contours.length; i++) { + EContour contour = (EContour) contours[i]; + list.add(contour.toQuadratic()); + } // for i + + XModule [] modules = m_glyph.getBody().getModule(); + for (int i = 0; i < modules.length; i++) { + EModuleInvoke module = (EModuleInvoke) modules[i]; + + // push and pop happens inside toContour + list.add(module.toContour(new AffineTransform())); + } // for i + + if (list.size() == 0) + return null; + + retval = new XContour[list.size()]; + for (int i = 0; i < list.size(); i++) { + retval[i] = list.get(i); + } // for i + + return retval; + } + + // -------------------------------------------------------------- + + public boolean isMoving() { + return m_isMoving; + } + + // -------------------------------------------------------------- + + public void beginMove() { + m_isMoving = true; + } + + // -------------------------------------------------------------- + + public void endMove() { + if (!m_isMoving) { + return; + } // if + + m_isMoving = false; + + m_history.record("move"); + } + + // -------------------------------------------------------------- + + public void move(Point2D a_delta) { + int i; + for (i = 0; i < m_actives.size(); i++) { + GlyphObject active = m_actives.get(i); + active.move(a_delta); + } // for i + } + + + // -------------------------------------------------------------- + + public void fitMove() { + if (m_actives.hasActiveControlPoint()) { + EControlPoint controlPoint = m_actives.getActiveControlPoint(); + controlPoint.rotateTo45(); + } // if + } + + // -------------------------------------------------------------- + + public boolean isHittingSelected(Point2D a_point) { + ActiveList oldActiveObjects = new ActiveList(); + oldActiveObjects.setActives(m_actives); + + m_actives.unselectAll(); + hit(a_point, false, false); + + int i, j; + for (i = 0; i < m_actives.size(); i++) { + GlyphObject selected = m_actives.get(i); + for (j = 0; j < oldActiveObjects.size(); j++) { + GlyphObject old = oldActiveObjects.get(j); + + if (selected == old) { + m_actives.setActives(oldActiveObjects); + return true; + } // if + } // for j + } // for i + + m_actives.setActives(oldActiveObjects); + + return false; + } + + // -------------------------------------------------------------- + + /** hits a point to add them in active object queue. + * @param a_single when it is true, the method returns after + * finding the first hit. + */ + public boolean hit(Point2D a_point, + boolean a_isAppend, + boolean a_isSelectOnlyOne) { + if (a_point == null) { + return false; + } // if + + Rectangle2D rect = new Rectangle2D.Double( + a_point.getX(), a_point.getY(), + 1.0, 1.0); + return hit(rect, a_isAppend, a_isSelectOnlyOne); + } + + public void selectNext() { + Iterator i = new SelectionIterator(this); + + if (m_actives.size() == 1) { + boolean isFound = false; + + // loop the iterator in reverse order of drawing + while (i.hasNext()) { + GlyphObject object = (GlyphObject) i.next(); + + if (m_actives.isSelected(object)) { + isFound = true; + continue; + } // if + + if (!isFound) { + continue; + } // if + + m_actives.unselectAll(); + m_actives.addActive(object); + return; + } // while i + } // if + + i = new SelectionIterator(this); + if (i.hasNext()) { + GlyphObject object = (GlyphObject) i.next(); + m_actives.unselectAll(); + m_actives.addActive(object); + return; + } // if + } + + // -------------------------------------------------------------- + + public boolean hit(Rectangle2D a_rect, + boolean a_isAppend, + boolean a_single) { + + + if (!a_isAppend) { + m_actives.unselectAll(); + } // if + + return hitObjects(a_rect, a_single); + } + + // -------------------------------------------------------------- + + private boolean hitObjects(Rectangle2D a_rect, boolean a_isSelectOnlyOne) { + boolean retval = false; + + Iterator i = new SelectionIterator(this); + + // loop the iterator in reverse order of drawing + while (i.hasNext()) { + GlyphObject object = (GlyphObject) i.next(); + + if (!object.hit(a_rect, new AffineTransform())) { + continue; + } // if + + retval = true; + + if (a_isSelectOnlyOne) { + return true; + } // if + } // while i + + return retval; + } + + // -------------------------------------------------------------- + + /** used for cut and paste. + */ + public void addObjectFromClipboard(String a_value) throws CircularIncludeException { + Reader reader = new StringReader(a_value); + Document document = null; + try { + document = UJAXP.getDocument(reader); + } catch (Exception e) { + e.printStackTrace(); + return; + } // try-catch + + Element root = document.getDocumentElement(); + if (!root.getNodeName().equals("clipboard")) { + return; + } // if + + Node child; + for (child = root.getFirstChild(); child != null; + child = child.getNextSibling()) { + if (!(child instanceof Element)) { + continue; + } // if + Element element = (Element) child; + + IGlyphFactory factory = GlyphFactory.getFactory(); + + + if (XModule.isMatch(element)) { + EModuleInvoke module = (EModuleInvoke) factory.createXModule(element); + addModule(module); + continue; + } // if + + if (XContour.isMatch(element)) { + EContour contour = (EContour) factory.createXContour(element); + addContour(contour); + continue; + } // if + + if (XInclude.isMatch(element)) { + EIncludeInvoke include = (EIncludeInvoke) factory.createXInclude(element); + addInclude(include); + continue; + } // if + } // while + } + + // -------------------------------------------------------------- + + private boolean isCircularInclude(String a_href) { + if (getShortFileName().equals(a_href)) { + return true; + } // if + + ModuleManager manager = ModuleManager.getSingletonInstance(); + XInclude [] includes = m_glyph.getBody().getInclude(); + int i; + for (i = 0; i < includes.length; i++) { + XInclude include = includes[i]; + GlyphFile child = manager.getGlyphFile(include.getHref()); + + if (child.isCircularInclude(a_href)) { + return true; + } // if + } // for i + + return false; + } + + // -------------------------------------------------------------- + + public void addInclude(String a_fileName) throws CircularIncludeException { + addInclude(EIncludeInvoke.create(a_fileName)); + } + + public void addInclude(XInclude a_include) throws CircularIncludeException { + if (isCircularInclude(a_include.getHref())) { + throw new CircularIncludeException(); + } // if + + m_actives.unselectAll(); + m_actives.addActive((GlyphObject) a_include); + m_glyph.getBody().addInclude(a_include); + m_history.record("addInclude"); + } + + // -------------------------------------------------------------- + + /** + * pasted module from clipboard or ModuleInvokeAction + * @param a_module + */ + public XModule addModule(EModuleInvoke a_module) { + m_actives.unselectAll(); + m_actives.addActive(a_module); + m_glyph.getBody().addModule(a_module); + m_history.record("addModule"); + + return a_module; + } + + // -------------------------------------------------------------- + + /** add contour from clipboard or ContourAction + * @param a_contour + */ + public void addContour(EContour a_contour) { + m_actives.unselectAll(); + m_actives.addActive(a_contour); + m_glyph.getBody().addContour(a_contour); + m_history.record("addContour"); + } + + + // -------------------------------------------------------------- + + + public void addPoint() { + if (!m_actives.hasActivePoint()) { + return; + } // if + + EContourPoint contourPoint = m_actives.getActivePoint(); + m_actives.unselectAll(); + m_actives.addActive(contourPoint.add()); + + m_history.record("addPoint"); + } + + // -------------------------------------------------------------- + + public void addHint(int a_ppem) { + if (!m_actives.hasActivePoint()) + return; + + EContourPoint contourPoint = m_actives.getActivePoint(); + m_actives.unselectAll(); + m_actives.addActive(contourPoint.addHint(a_ppem)); + + if (contourPoint.hasControlPoint1()) { + EContourPoint p = (EContourPoint) contourPoint.getControlPoint1().getContourPoint(); + m_actives.addActive(p.addHint(a_ppem)); + } // if + + if (contourPoint.hasControlPoint2()) { + EContourPoint p = (EContourPoint) contourPoint.getControlPoint2().getContourPoint(); + m_actives.addActive(p.addHint(a_ppem)); + } // if + + + m_history.record("addHint"); + } + + public void toggleRounded() { + if (!m_actives.hasActivePoint()) + return; + + EContourPoint contourPoint = m_actives.getActivePoint(); + contourPoint.toggleRounded(); + + m_history.record("toggleGridfit"); + } + + public void convertControlPoint() { + if (!m_actives.hasActiveControlPoint()) { + return; + } // if + + EControlPoint controlPoint = m_actives.getActiveControlPoint(); + controlPoint.convert(); + + m_history.record("convertControlPoint"); + } + + public void convertContour() { + if (!m_actives.hasActiveContour()) { + return; + } // if + + EContour contour = m_actives.getActiveContour(); + contour.convert(); + + m_history.record("convertContour"); + } + + // -------------------------------------------------------------- + + public void remove() { + if (!m_actives.hasSelected()) + return; + + int i; + for (i = 0; i < m_actives.size(); i++) { + GlyphObject active = m_actives.get(i); + active.remove(); + } // for i + + m_history.record("remove"); + + m_actives.unselectAll(); + } + + // -------------------------------------------------------------- + + public void toggleOnOff() { + if (!m_actives.hasSelected()) + return; + + int i; + for (i = 0; i < m_actives.size(); i++) { + GlyphObject active = m_actives.get(i); + if (!(active instanceof EContourPoint)) { + continue; + } // if + + EContourPoint point = (EContourPoint) active; + point.toggleOnCurve(); + } // for i + + m_history.record("toggleOnOff"); + } + + private void loadVar() { + XParamListParam [] params = m_glyph.getHead().getHeadGlobal().getParamListParam(); + int i; + for (i = 0; i < params.length; i++) { + XParamListParam param = params[i]; + addVar(param.getName(), param.getContent()); + } // for i + } + + public String getSelectedNodeName() { + return m_selectedNodeName; + } + + public void addFileVar() { + XParamListParam param = new XParamListParam(); + param.setName("New parameter"); + param.setContent(0.0); + m_history.record("addFileVar"); + + m_glyph.getHead().getHeadGlobal().addParamListParam(param); + } + + public void removeFileVar(int a_index) { + m_history.record("removeFileVar"); + + m_glyph.getHead().getHeadGlobal().removeParamListParam(a_index); + } + + + public void addInvokeArg(int a_type) { + + } + + public void removeInvokeArg(int a_type, int a_index) { + + } + + public String getIncludeName() { + String retval = ""; + + if (!m_actives.hasActiveInclude()) + return retval; + retval = m_actives.getActiveInclude().getHref(); + + return retval; + } + + public void setIncludeName(String a_name) { + if (!m_actives.hasActiveInclude()) + return; + + m_actives.getActiveInclude().setHref(a_name); + m_history.record("setIncludeName"); + } + + public void setGlyphTitle(String a_title) { + m_glyph.getHead().setTitle(a_title); + m_history.record("setGlyphTitle"); + } + + public String getGlyphTitle() { + String retval = ""; + + retval = m_glyph.getHead().getTitle(); + + if (retval.equals("empty")) { + retval = ""; + } // if + + return retval; + } + + public String getModuleName() { + String retval = ""; + + if (!m_actives.hasActiveModule()) + return retval; + retval = m_actives.getActiveModule().getName(); + + return retval; + } + + public String getUnicode() { + return getUnicodeAsString(); + } + + public String getUnicodeAsString() { + return m_glyph.getHead().getUnicode(); + } + + public long getUnicodeAsLong() { + long retval = -1; + + String s = getUnicodeAsString(); + if (s.equals("")) { + return retval; + } // if + + try { + retval = Long.parseLong(s, 16); + } catch (NumberFormatException e) { + retval = -1; + } // try-catch + + return retval; + } + + protected void setUnicode(String a_unicode) { + m_glyph.getHead().setUnicode(a_unicode); + m_history.record("setUnicode"); + } + + public boolean isSimple() { + return (m_glyph.getBody().getInclude().length == 0); + } + + public boolean isWhiteSpace() { + long unicode = getUnicodeAsLong(); + + if (unicode == 0x0020 + || unicode == 0x00a0 + || unicode == 0x200b + || unicode == 0x2060 + || unicode == 0x3000 + || unicode == 0xfeff) + { + return true; + } // if + + return false; + } + + public String getShortFileName() { + return m_fileName.getName(); + } + + public void setLicense(String a_value) { + m_glyph.getHead().setLicense(a_value); + m_history.record("setLicense"); + } + + public String getLicense() { + return m_glyph.getHead().getLicense(); + } + + public PointAggregate getPointHost() { + return m_pointHost; + } + + public void buildPointHost() { + m_pointHost = null; + + /*if (!GlyphAction.isPointVisible()) { + return; + } // if*/ + + int i; + for (i = 0; i < m_actives.size(); i++) { + GlyphObject object = (GlyphObject) m_actives.get(i); + PointAggregate host = null; + + if (object instanceof EContourPoint) { + EContourPoint point = (EContourPoint) object; + host = point.getParent(); + + if (host instanceof EContourPoint) { + EContourPoint hostPoint = (EContourPoint) host; + host = hostPoint.getParent(); + } // if + } else if (object instanceof EHint) { + EHint hint = (EHint) object; + host = hint.getPointHost(); + } // if-else + + if (host == null) { + continue; + } // if + + if (m_pointHost == null) { + m_pointHost = host; + } else { + if (m_pointHost != host) { + m_pointHost = null; + return; + } // if + } // if + } // while + } + + public boolean isRequiredGlyph() { + long unicode = getUnicodeAsLong(); + + return (unicode == TTUnicodeRange.k_notDef + || unicode == TTUnicodeRange.k_null + || unicode == TTUnicodeRange.k_cr + || unicode == TTUnicodeRange.k_space); + } + + public TTGlyph toSimpleGlyph() { + // convert the file into array of contours + XContour [] contours = toContours(); + if ((contours == null) && (!isRequiredGlyph())) { + return null; + } // if + + TTGlyph retval = new TTGlyph(); + retval.setSimple(true); + retval.setAdvanceWidth(getAdvanceWidth()); + + if (contours == null) { + return retval; + } // if + + ArrayList points = new ArrayList<>(); + for (int i = 0; i < contours.length; i++) { + XContour contour = contours[i]; + XContourPoint [] contourPoints = contour.getContourPoint(); + for (int j = 0; j < contourPoints.length; j++) { + points.add((EContourPoint) contourPoints[j]); + } // for j + retval.addEndPoint(points.size() - 1); + } // for i + + for (EContourPoint point: points) { + loadContourPoint(retval, point); + } // for point + + boolean hasGridfit = false; + // I need int i here. + for (int i = 0; i < points.size(); i++) { + EContourPoint point = points.get(i); + + if (!point.isRounded()) { + continue; + } // if + + hasGridfit = true; + loadGridfit(retval, point, i); + } // for i + + if (hasGridfit) { + retval.addInstruction(TTGlyph.IUP1); + retval.addInstruction(TTGlyph.IUP0); + } // if + + // I need int i here. + for (int i = 0; i < points.size(); i++) { + EContourPoint point = points.get(i); + if (point.getHint().length == 0) { + continue; + } // if + + loadHint(retval, point, i); + } // for i + + return retval; + } + + private void loadContourPoint(TTGlyph a_glyph, EContourPoint a_point) { + double x = a_point.getX(); + double y = a_point.getY(); + Point p = new Point((int) x, (int) y); + int flag = 0; + if (a_point.isOn()) { + flag = TTGlyph.k_onCurve; + } // if + + a_glyph.addPoint(p); + a_glyph.addFlag(flag); + } + + private void loadGridfit(TTGlyph a_glyph, EContourPoint a_point, int a_index) { + if (!a_point.isRounded()) { + return; + } // if + + a_glyph.addInstruction(TTGlyph.PUSHB000); + a_glyph.addInstruction(a_index); + a_glyph.addInstruction(TTGlyph.MDAP1); + } + + + private void loadHint(TTGlyph a_glyph, EContourPoint a_point, int a_index) { + double x = a_point.getX(); + double y = a_point.getY(); + + XHint [] hints = a_point.getHint(); + + for (int i = 0; i < hints.length; i++) { + EHint hint = (EHint) hints[i]; + double xHint = hint.getX(); + double yHint = hint.getY(); + + if (x == xHint && y == yHint) { + continue; + } // if + + double xDelta = xHint - x; + double yDelta = yHint - y; + int instruction = TTGlyph.DELTAP1; + double deltaStep = ((double) Engine.getEm()) / hint.getPpem() / 8; + int xShift = (int) Math.round(xDelta / deltaStep); + int yShift = (int) Math.round(yDelta / deltaStep); + + if (xShift == 0 && yShift == 0) { + continue; + } // if + + a_glyph.addInstruction(TTGlyph.PUSHB000); + a_glyph.addInstruction((int) hint.getPpem()); + a_glyph.addInstruction(TTGlyph.SDB); + + if (xShift != 0) { + a_glyph.addInstruction(TTGlyph.SVTCA1); + a_glyph.addInstruction(TTGlyph.PUSHB010); + a_glyph.addInstruction(TTGlyph.toDeltaArg(0, xShift)); + a_glyph.addInstruction(a_index); + a_glyph.addInstruction(1); + a_glyph.addInstruction(TTGlyph.DELTAP1); + } // if + + if (yShift != 0) { + a_glyph.addInstruction(TTGlyph.SVTCA0); + a_glyph.addInstruction(TTGlyph.PUSHB010); + a_glyph.addInstruction(TTGlyph.toDeltaArg(0, yShift)); + a_glyph.addInstruction(a_index); + a_glyph.addInstruction(1); + a_glyph.addInstruction(TTGlyph.DELTAP1); + } // if + } // for i + } + + public class CircularIncludeException extends Exception {} +} \ No newline at end of file diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/module/GlyphIterator.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/module/GlyphIterator.java new file mode 100644 index 000000000..d606360f5 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/module/GlyphIterator.java @@ -0,0 +1,237 @@ + /* + * $Id: GlyphIterator.java,v 1.11 2004/12/27 04:56:03 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003-2004, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa.module; + +import java.util.*; + +import org.doubletype.ossa.xml.*; +import org.doubletype.ossa.adapter.*; + +/** Iterates through contours, module invokes, then include invokes. + * Used in GlyphFile display + * @author e.e + */ +public class GlyphIterator implements Iterator { + protected GlyphFile m_file; + private int m_index = 0; + protected java.util.List m_list = new ArrayList<>(); + + public GlyphIterator(GlyphFile a_file) { + m_file = a_file; + buildList(); + } + + protected void buildList() { + addIncludes(); + addContours(); + addModules(); + + } + + protected void addContours() { + XContour [] contours = m_file.getGlyph().getBody().getContour(); + for (int i = 0; i < contours.length; i++) { + m_list.add(contours[i]); + } // for i + } + + protected void addControlPoints() { + XContour [] contours = m_file.getGlyph().getBody().getContour(); + for (int i = 0; i < contours.length; i++) { + EContour contour = (EContour) contours[i]; + if (!contour.isCubic()) { + continue; + } // if + + addControlPoints(contour, 0, 0); + } // for i + } + + private void addControlPoints(PointAggregate a_object, double a_x, double a_y) { + XContourPoint [] points = a_object.getContourPoint(); + + for (int i = 0; i < points.length; i++) { + EContourPoint point = (EContourPoint) points[i]; + + if (!isPointVisible(point)) { + continue; + } // if + + if (point.hasControlPoint1()) { + EControlPoint controlPoint = (EControlPoint) point.getControlPoint1(); + controlPoint.setOffset(a_x, a_y); + m_list.add(controlPoint); + } // if + + if (point.hasControlPoint2()) { + EControlPoint controlPoint = (EControlPoint) point.getControlPoint2(); + controlPoint.setOffset(a_x, a_y); + m_list.add(controlPoint); + } // if + } // for j + } + + protected void addHints() { + XContour [] contours = m_file.getGlyph().getBody().getContour(); + for (int i = 0; i < contours.length; i++) { + addHints((EContour) contours[i], 0, 0); + } // for i + + XModule [] modules = m_file.getGlyph().getBody().getModule(); + for (int i = 0; i < modules.length; i++) { + EModuleInvoke module = (EModuleInvoke) modules[i]; + double x = module.getInvoke().getInvokePos().getPoint2d().getX(); + double y = module.getInvoke().getInvokePos().getPoint2d().getY(); + + addHints(module, x, y); + } // for i + } + + private void addHints(PointAggregate a_object, double a_x, double a_y) { + XContourPoint [] points = a_object.getContourPoint(); + + for (int i = 0; i < points.length; i++) { + EContourPoint point = (EContourPoint) points[i]; + + if (!isPointVisible(point)) { + continue; + } // if + + if (point.hasHintForCurrentPpem()) { + EHint hint = point.getCurrentHint(); + hint.setOffset(a_x, a_y); + m_list.add(hint); + } // if + + if (point.hasControlPoint1()) { + EContourPoint p = (EContourPoint) point.getControlPoint1().getContourPoint(); + if (p.hasHintForCurrentPpem()) { + EHint hint = p.getCurrentHint(); + hint.setOffset(a_x, a_y); + m_list.add(hint); + } // if + } + + if (point.hasControlPoint2()) { + EContourPoint p = (EContourPoint) point.getControlPoint2().getContourPoint(); + if (p.hasHintForCurrentPpem()) { + EHint hint = p.getCurrentHint(); + hint.setOffset(a_x, a_y); + m_list.add(hint); + } // if + } // if + } // for j + } + + private boolean isPointVisible(EContourPoint a_point) { + if (m_file.getPointHost() == null) { + return true; + } // if + + if (m_file.getPointHost() == a_point.getParent()) { + return true; + } // if + + return false; + } + + protected void addPoints() { + XContour [] contours = m_file.getGlyph().getBody().getContour(); + for (int i = 0; i < contours.length; i++) { + addPoints((EContour) contours[i], 0, 0); + } // for i + + XModule [] modules = m_file.getGlyph().getBody().getModule(); + for (int i = 0; i < modules.length; i++) { + EModuleInvoke module = (EModuleInvoke) modules[i]; + double x = module.getInvoke().getInvokePos().getPoint2d().getX(); + double y = module.getInvoke().getInvokePos().getPoint2d().getY(); + + addPoints(module, x, y); + } // for i + } + + private void addPoints(PointAggregate a_object, double a_x, double a_y) { + XContourPoint [] points = a_object.getContourPoint(); + + for (int i = 0; i < points.length; i++) { + EContourPoint point = (EContourPoint) points[i]; + + if (!isPointVisible(point)) { + continue; + } // if + + point.setNumber(i); + point.setOffset(a_x, a_y); + m_list.add(point); + } // for j + } + + protected void addModules() { + XModule [] modules = m_file.getGlyph().getBody().getModule(); + for (int i = 0; i < modules.length; i++) { + m_list.add(modules[i]); + } // for i + } + + protected void addIncludes() { + XInclude [] includes = m_file.getGlyph().getBody().getInclude(); + for (int i = 0; i < includes.length; i++) { + m_list.add(includes[i]); + } // for i; + } + + /* (non-Javadoc) + * @see java.util.Iterator#remove() + */ + public void remove() { + + } + + /* (non-Javadoc) + * @see java.util.Iterator#hasNext() + */ + public boolean hasNext() { + return m_index < m_list.size(); + } + + /* (non-Javadoc) + * @see java.util.Iterator#next() + */ + public Object next() { + return m_list.get(m_index++); + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/module/GlyphModule.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/module/GlyphModule.java new file mode 100644 index 000000000..0027252aa --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/module/GlyphModule.java @@ -0,0 +1,90 @@ +/* + * $Id: GlyphModule.java,v 1.12 2004/09/04 21:54:19 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa.module; + +import org.doubletype.ossa.adapter.*; +import org.doubletype.ossa.*; +import java.util.*; + +/** + * @author e.e + */ +public class GlyphModule implements VarStackFrame { + protected VarStack m_stack = VarStack.getSingletonInstance(); + private Hashtable m_vars = new Hashtable<>(); + protected ActiveList m_actives = ActiveList.getSingletonInstance(); + + // -------------------------------------------------------------- + + public GlyphModule() { + } + + public Hashtable getVars() { + return m_vars; + } + + // for var stack frame + public boolean hasVariable(String a_name) { + return m_vars.containsKey(a_name); + } + + // for var stack frame. + public double getValue(String a_name) { + Double d = (Double) m_vars.get(a_name); + return d.doubleValue(); + } + + // for var stack frame. + public void beforePush() { + } + + /** + * Base for generating contours from modules. + * @param a_moduleInvoke + * @return XContour object which represents the module. + */ + public EContour toContour(EModuleInvoke a_moduleInvoke) { + throw new RuntimeException("Unimplemented contour creation."); + } + + public void addVar(String a_name, double a_value) { + m_vars.put(a_name, new Double(a_value)); + } + + public int getMinimumPointCount() { + return 2; + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/module/Rectangle.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/module/Rectangle.java new file mode 100644 index 000000000..813dfcbb8 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/module/Rectangle.java @@ -0,0 +1,192 @@ +/* + * $Id: Rectangle.java,v 1.16 2004/09/04 21:54:19 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa.module; + +import org.doubletype.ossa.xml.*; +import org.doubletype.ossa.adapter.*; + +import java.awt.geom.*; + +/** + * @author e.e + * + */ +public class Rectangle extends GlyphModule { + public static final double k_defaultPen = 68.0; + public static final double k_defaultWeight = 1.0; + public static final String k_weight = "weight"; + + public Rectangle() { + super(); + + addVar(k_weight, k_defaultWeight); + } + + public EContour toContour(EModuleInvoke a_moduleInvoke) { + int i; + EContour retval = new EContour(); + XContourPoint[] points = a_moduleInvoke.getContourPoint(); + + // can't make rectangle with one or zero point + if (points.length < 2) { + retval.addContourPoint(new EContourPoint(0, 0, true)); + return retval; + } // if + + double pen = m_stack.get(k_weight) * k_defaultPen; + boolean steeps[] = new boolean[points.length - 1]; + double thetas[] = new double[points.length - 1]; + Point2D outStartPoints[] = new Point2D[points.length - 1]; + Point2D inStartPoints[] = new Point2D[points.length - 1]; + Point2D outPoints [] = new Point2D[points.length]; + Point2D inPoints[] = new Point2D[points.length]; + + // treat each segment as a vector (start point and theta) + for (i = 0; i < points.length - 1; i++) { + EContourPoint start = (EContourPoint) points[i]; + EContourPoint end = (EContourPoint) points[i + 1]; + + // calculate theta of the vector + double theta; + if (start.toPoint2D().distance(end.toPoint2D()) > 0) { + theta = Math.atan2(end.getY() - start.getY(), + end.getX() - start.getX()); + } else { + theta = 0.0; + } // if + + thetas[i] = theta; + outStartPoints[i] = start.toPoint2D(); + + // turn the vector 90 degrees clockwise to create the + // starting point of the parallel vector (in-vector) + inStartPoints[i] = new Point2D.Double(start.getX() + (pen * Math.cos(theta - Math.PI / 2)), + start.getY() + (pen * Math.sin(theta - Math.PI / 2)) ); + } // for i + + for (i = 0; i < points.length; i++) { + EContourPoint point = (EContourPoint) points[i]; + + if (i == 0) { + // dynamically generate the point using vertical line thru p0 and the ideal line. + double cuttingTheta; + if (isSteep(thetas[i])) { + cuttingTheta = 0.0; + } else { + cuttingTheta = Math.PI / 2; + } // if-else + + outPoints[i] = getIntersection(point.toPoint2D(), cuttingTheta, + outStartPoints[i], thetas[i]); + inPoints[i] = getIntersection(point.toPoint2D(), cuttingTheta, + inStartPoints[i], thetas[i]); + continue; + } else if (i == points.length - 1) { + // vertial and ideal. + double cuttingTheta; + if (isSteep(thetas[i - 1])) { + cuttingTheta = 0.0; + } else { + cuttingTheta = Math.PI / 2; + } // if + + outPoints[i] = getIntersection(point.toPoint2D(), cuttingTheta, + outStartPoints[i - 1], thetas[i - 1]); + inPoints[i] = getIntersection(point.toPoint2D(), cuttingTheta, + inStartPoints[i - 1], thetas[i - 1]); + + continue; + } // if + + if (thetas[i - 1] != thetas[i]) { + outPoints[i] = getIntersection(outStartPoints[i - 1], thetas[i - 1], + outStartPoints[i], thetas[i]); + inPoints[i] = getIntersection(inStartPoints[i - 1], thetas[i - 1], + inStartPoints[i], thetas[i]); + } else { + outPoints[i] = outStartPoints[i]; + inPoints[i] = inStartPoints[i]; + } // if + } // for i + + for (i = 0; i < points.length; i++) { + EContourPoint point = (EContourPoint) points[i]; + + retval.addContourPoint(i, point.cloneAt(outPoints[i])); + retval.addContourPoint(i + 1, point.cloneAt(inPoints[i])); + } // if + + return retval; + } + + private boolean isSteep(double a_theta) { + return (a_theta > (Math.PI / 4) && a_theta < (3 * Math.PI / 4)) + || (a_theta < (-Math.PI / 4) && a_theta > (-3 * Math.PI / 4)); + } + + /** + * Intersection of two lines line0 and line1, defined by a point and slope. + * @param a_p0 a point line0 goes thru. + * @param a_theta0 the slope of line0, given in radian. + * @param a_p1 a point line1 goes thru. + * @param a_theta1 the slope of line1, given in radian. + * @return the intersection of line0 and line1, if any; a_p1, otherwise. + */ + private Point2D getIntersection(Point2D a_p0, double a_theta0, + Point2D a_p1, double a_theta1) { + Point2D retval = new Point2D.Double(); + retval.setLocation(a_p1); + + if (a_theta0 == a_theta1) + return retval; + + double cos0 = Math.cos(a_theta0); + double sin0 = Math.sin(a_theta0); + double cos1 = Math.cos(a_theta1); + double sin1 = Math.sin(a_theta1); + double deltaX = a_p1.getX() - a_p0.getX(); + double deltaY = a_p1.getY() - a_p0.getY(); + + double r1 = (cos0 * deltaY - sin0 * deltaX) + / (sin0 * cos1 - cos0 * sin1); + double x = a_p1.getX() + cos1 * r1; + double y = a_p1.getY() + sin1 * r1; + + retval.setLocation(x, y); + + return retval; + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/module/SelectionIterator.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/module/SelectionIterator.java new file mode 100644 index 000000000..14bb377b4 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/module/SelectionIterator.java @@ -0,0 +1,69 @@ + /* + * $Id: SelectionIterator.java,v 1.2 2004/11/08 06:29:52 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2004, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa.module; + +import java.util.*; + +import org.doubletype.ossa.adapter.*; +import org.doubletype.ossa.xml.IRNode; + + +/** + * @author e.e + */ +public class SelectionIterator extends GlyphIterator implements Iterator { + + /** + * @param a_file + */ + public SelectionIterator(GlyphFile a_file) { + super(a_file); + } + + protected void buildList() { + super.buildList(); + + List reverseList = new ArrayList<>(); + for (int i = m_list.size() - 1; i >= 0; i--) { + IRNode object = m_list.get(i); + + + reverseList.add(object); + } // for i + + m_list = reverseList; + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/module/TypefaceFile.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/module/TypefaceFile.java new file mode 100644 index 000000000..9133ea84f --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/module/TypefaceFile.java @@ -0,0 +1,677 @@ +/* + * $Copyright: copyright (c) 2003-2008, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa.module; + +import java.io.*; +import java.util.*; + +import org.doubletype.ossa.*; +import org.doubletype.ossa.xml.*; +import org.doubletype.ossa.adapter.*; +import org.doubletype.ossa.truetype.*; +import java.awt.*; + +/** + * @author e.e + */ +public class TypefaceFile extends GlyphFile { + private final double k_defaultTopSideBearing = 170; // 2 px + private final double k_defaultAscender = 683; // 8 px + private final double k_defaultXHeight = 424; // 5 px + private final double k_defaultDescender = 171; // 2 px + private final double k_defaultBottomSideBearing = 0; // 0 px + private final double k_em = 1024; + private final int k_defaultAdvanceWidth = 512; + private final String k_dotDtyp = ".dtyp"; + private final String k_dotTtf = ".ttf"; + + private File m_dir; + private Hashtable m_nameToIndeces = new Hashtable<>(); + private File m_ttfFile; + private Font m_font = null; + private File m_binFolder; + + public TypefaceFile(String a_name, File a_dir) throws FileNotFoundException { + super(TypefaceFile.class.getResource(s_emptyFileName)); + + m_dir = a_dir; + setGlyphTitle(a_name); + + m_fileName = new File(m_dir, a_name + k_dotDtyp); + initFileName(); + + saveGlyphFile(); + } + + public TypefaceFile(File a_file) { + super(a_file); + + m_dir = a_file.getParentFile(); + m_fileName = a_file; + + initFileName(); + } + + private void initFileName() { + m_binFolder = new File(m_dir, "bin"); + if (!m_binFolder.exists()) { + m_binFolder.mkdir(); + } // if + + String fileName = getGlyphTitle() + k_dotTtf; + m_ttfFile = new File(m_binFolder, fileName); + } + + public GlyphFile createGlyph(long a_unicode) throws FileNotFoundException { + String name = Character.getName((int) a_unicode); + if (name == null) { + name = "NAC_" + Long.toHexString(a_unicode); + } // if + + name = name.replace(' ', '_'); + return new GlyphFile( + getGlyphPath(), name, a_unicode); + } + + public boolean addRequiredGlyphs() throws FileNotFoundException { + boolean retval = false; + + if (unicodeToFileName(TTUnicodeRange.k_notDef) == null) { + GlyphFile glyph = new GlyphFile(getGlyphPath(), "NOTDEF", TTUnicodeRange.k_notDef); + glyph.initNotDef(k_defaultAdvanceWidth); + addGlyph(0, glyph); + retval = true; + } // if + + if (unicodeToFileName(TTUnicodeRange.k_null) == null) { + GlyphFile glyph = new GlyphFile(getGlyphPath(), "NULL", TTUnicodeRange.k_null); + glyph.initNullGlyph(); + addGlyph(1, glyph); + retval = true; + } // if + + if (unicodeToFileName(TTUnicodeRange.k_cr) == null) { + GlyphFile glyph = new GlyphFile(getGlyphPath(), "CR", TTUnicodeRange.k_cr); + glyph.initSpace(k_defaultAdvanceWidth); + addGlyph(2, glyph); + retval = true; + } // if + + if (unicodeToFileName(TTUnicodeRange.k_space) == null) { + GlyphFile glyph = new GlyphFile(getGlyphPath(), "SPACE", TTUnicodeRange.k_space); + glyph.initSpace(k_defaultAdvanceWidth); + addGlyph(3, glyph); + retval = true; + } // if + + if (retval) { + saveGlyphFile(); + } // if + + return retval; + } + + public void addBasicLatinGlyphs() throws FileNotFoundException { + String basicLatin = Character.UnicodeBlock.BASIC_LATIN.toString(); + TTUnicodeRange.find(basicLatin); + TTUnicodeRange range = TTUnicodeRange.getLastFound(); + addUnicodeRange(basicLatin); + for (long i = range.getStartCode(); i <= range.getEndCode(); i++) { + if (i != 0x0020) { + addGlyph(createGlyph(i)); + } // if + } // for i + + saveGlyphFile(); + } + + public File getGlyphPath() { + return m_dir; + } + + public String unicodeToFileName(long a_unicode) { + for (XGlyphFile glyphFile: m_glyph.getBody().getGlyphFile()) { + if (glyphFile.getUnicode() == a_unicode) { + return glyphFile.getHref(); + } // if + } // for i + + return null; + } + + /** + * change glyph's unicode mapping. + * @param a_glyphFile + * @param a_unicode + */ + public void setGlyphUnicode(GlyphFile a_glyphFile, long a_unicode) throws FileNotFoundException { + int i; + XGlyphFile [] glyphFiles = m_glyph.getBody().getGlyphFile(); + for (i = 0; i < glyphFiles.length; i++) { + XGlyphFile glyphFile = glyphFiles[i]; + + if (glyphFile.getHref().equals( + a_glyphFile.getShortFileName())) { + continue; + } // if + + glyphFile.setUnicode(a_unicode); + a_glyphFile.setUnicode(Long.toHexString(a_unicode)); + a_glyphFile.saveGlyphFile(); + saveGlyphFile(); + + return; + } // for i + } + + public void addGlyph(GlyphFile a_file) { + XGlyphFile xglyphFile = new XGlyphFile(); + xglyphFile.setHref(a_file.getShortFileName()); + xglyphFile.setUnicode(a_file.getUnicodeAsLong()); + m_glyph.getBody().addGlyphFile(xglyphFile); + } + + public void addGlyph(int a_index, GlyphFile a_file) { + XGlyphFile xglyphFile = new XGlyphFile(); + xglyphFile.setHref(a_file.getShortFileName()); + xglyphFile.setUnicode(a_file.getUnicodeAsLong()); + m_glyph.getBody().addGlyphFile(a_index, xglyphFile); + } + + public void removeGlyph(String a_fileName) { + for (XGlyphFile file: m_glyph.getBody().getGlyphFile()) { + if (file.getHref().equals(a_fileName)) { + m_glyph.getBody().removeGlyphFile(file); + return; + } // if + } + } + + public ArrayList getChildFileNames() { + ArrayList retval = new ArrayList<>(); + XGlyphFile [] files = m_glyph.getBody().getGlyphFile(); + + for (int i = 0; i < files.length; i++) { + XGlyphFile file = files[i]; + retval.add(file.getHref()); + } // for i + + return retval; + } + + public Object [] getCodePages() { + int i; + Object [] retval; + String [] codePages = m_glyph.getHead().getCodePage(); + retval = new Object[codePages.length]; + for (i = 0; i < codePages.length; i++) { + retval[i] = codePages[i]; + } // for i + + return retval; + } + + public boolean containsUnicodeRange(String a_unicodeRange) { + int i; + String [] unicodeRanges = m_glyph.getHead().getUnicodeRange(); + + for (i = 0; i < unicodeRanges.length; i++) { + if (unicodeRanges[i].equals(a_unicodeRange)) { + return true; + } // if + } // for i + + return false; + } + + public void addUnicodeRange(String a_unicodeRange) throws FileNotFoundException { + if (containsUnicodeRange(a_unicodeRange)) { + return; + } // if + + m_glyph.getHead().addUnicodeRange(a_unicodeRange); + saveGlyphFile(); + } + + public boolean containsCodePage(String a_codePage) { + int i; + String [] codePages = m_glyph.getHead().getCodePage(); + + for (i = 0; i < codePages.length; i++) { + if (codePages[i].equals(a_codePage)) { + return true; + } // if + } // for i + + return false; + } + + public void addCodePage(String a_codePage) throws FileNotFoundException { + if (containsCodePage(a_codePage)) { + return; + } // if + + m_glyph.getHead().addCodePage(a_codePage); + saveGlyphFile(); + } + + public void removeCodePage(String a_codePage) throws FileNotFoundException { + if (!containsCodePage(a_codePage)) { + return; + } // if + + m_glyph.getHead().removeCodePage(a_codePage); + saveGlyphFile(); + } + + public void setFontFamilyName(String a_value) throws FileNotFoundException { + m_glyph.getHead().setFontFamily(a_value); + saveGlyphFile(); + } + + public String getFontFamilyName() { + return m_glyph.getHead().getFontFamily(); + } + + public String getVersion() throws FileNotFoundException { + if (m_glyph.getHead().getVersion() == null) { + m_glyph.getHead().setVersion("0.1"); + saveGlyphFile(); + } // if + + return m_glyph.getHead().getVersion(); + } + + public void setSubFamily(String a_value) throws FileNotFoundException { + m_glyph.getHead().setFontSubFamily(a_value); + saveGlyphFile(); + } + + public void setDefaultMetrics() throws FileNotFoundException { + XHead head = m_glyph.getHead(); + head.setTopSideBearing(k_defaultTopSideBearing); + head.setAscender(k_defaultAscender); + head.setXHeight(k_defaultXHeight); + head.setDescender(k_defaultDescender); + head.setBottomSideBearing(k_defaultBottomSideBearing); + + saveGlyphFile(); + } + + public double getEm() { + return k_em; + } + + public double getBaseline() throws FileNotFoundException { + return getBottomSideBearing() + getDescender(); + } + + public double getMeanline() throws FileNotFoundException { + return getBottomSideBearing() + + getDescender() + getXHeight(); + } + + public double getBodyBottom() throws FileNotFoundException { + return getBottomSideBearing(); + } + + public double getBodyTop() throws FileNotFoundException { + return getEm() - getTopSideBearing(); + } + + public double getTopSideBearing() throws FileNotFoundException { + if (!m_glyph.getHead().checkTopSideBearing()) { + setDefaultMetrics(); + } // if + + return m_glyph.getHead().getTopSideBearing(); + } + + public double getAscender() throws FileNotFoundException { + if (!m_glyph.getHead().checkAscender()) { + setDefaultMetrics(); + } // if + + return m_glyph.getHead().getAscender(); + } + + public double getXHeight() throws FileNotFoundException { + if (!m_glyph.getHead().checkXHeight()) { + setDefaultMetrics(); + } // if + + return m_glyph.getHead().getXHeight(); + } + + public double getDescender() throws FileNotFoundException { + if (!m_glyph.getHead().checkDescender()) { + setDefaultMetrics(); + } // if + + return m_glyph.getHead().getDescender(); + } + + public double getBottomSideBearing() throws FileNotFoundException { + if (!m_glyph.getHead().checkBottomSideBearing()) { + setDefaultMetrics(); + } // if + + return m_glyph.getHead().getBottomSideBearing(); + } + + public void setTopSideBearing(double a_value) throws OutOfRangeException, FileNotFoundException { + checkBoundary(a_value); + m_glyph.getHead().setTopSideBearing(a_value); + saveGlyphFile(); + } + + private void checkBoundary(double a_value) throws OutOfRangeException { + if (a_value > k_em || a_value < 0) { + throw new OutOfRangeException(a_value); + } // if + } + + public void setAscender(double a_value) throws OutOfRangeException, FileNotFoundException { + checkBoundary(a_value); + m_glyph.getHead().setAscender(a_value); + saveGlyphFile(); + } + + public void setXHeight(double a_value) throws OutOfRangeException, FileNotFoundException { + checkBoundary(a_value); + if (a_value > getAscender()) { + throw new OutOfRangeException(a_value); + } // if + + m_glyph.getHead().setXHeight(a_value); + + m_history.record("setXHeight"); + saveGlyphFile(); + } + + public void setDescender(double a_value) throws OutOfRangeException, FileNotFoundException { + checkBoundary(a_value); + m_glyph.getHead().setDescender(a_value); + saveGlyphFile(); + } + + public void setBottomSideBearing(double a_value) throws OutOfRangeException, FileNotFoundException { + checkBoundary(a_value); + m_glyph.getHead().setBottomSideBearing(a_value); + saveGlyphFile(); + } + + public double getBodyHeight() throws FileNotFoundException { + return k_em - getTopSideBearing() - getBottomSideBearing(); + } + +// -------------------------------------------------------------------- + + /** + * Calls FontFileWriter to produce TrueType font file. + * @throws FileNotFoundException + */ + public void buildTTF(boolean a_isDebug) throws Exception { + String randomString = UUID.randomUUID().toString().substring(0, 4); + + File tempFile = new File(m_binFolder, + getGlyphTitle() + "_" + randomString + k_dotTtf); + File target; + String fontFamilyName; + + if (a_isDebug) { + target = tempFile; + fontFamilyName = getGlyphTitle() + " " + randomString; + } else { + target = m_ttfFile; + fontFamilyName = getFontFamilyName(); + } // if-else + + target.delete(); + FontFileWriter writer; + ModuleManager.getSingletonInstance().clear(); + m_stack.clear(); + m_stack.push(this); + try (RandomAccessFile randomAccessFile = new RandomAccessFile(target, "rw")) { + writer = new FontFileWriter(randomAccessFile); + + writer.setFontFamilyName(fontFamilyName); + writer.setCopyrightYear(getCopyrightYear()); + writer.setFontVersion(getVersion()); + writer.setManufacturer(getAuthor()); + writer.setAscent((int) getAscender()); + writer.setXHeight((int) getXHeight()); + writer.setDescent((int) getDescender()); + writer.setLineGap((int) (getTopSideBearing() + getBottomSideBearing())); + + loadCodePages(writer); + loadUnicodeRanges(writer); + loadGlyphs(writer); + writer.write(); + } + if (!a_isDebug && target.exists()) { + copyFile(target, tempFile); + } // if + + FileInputStream in = new FileInputStream(tempFile); + m_font = Font.createFont(Font.TRUETYPE_FONT, + (InputStream) in); + in.close(); + + ModuleManager.getSingletonInstance().clear(); + m_stack.pop(); // pop this + } + + private void copyFile(File a_in, File a_out) throws Exception { + FileInputStream in = new FileInputStream(a_in); + FileOutputStream out = new FileOutputStream(a_out); + byte [] buffer = new byte[1024]; + int i = 0; + while ((i = in.read(buffer)) != -1) { + out.write(buffer, 0, i); + } // while + + in.close(); + out.close(); + } + + public Font getFont() { + return m_font; + } + + private void loadCodePages(FontFileWriter a_writer) { + for (String codePageName: m_glyph.getHead().getCodePage()) { + TTCodePage codePage = TTCodePage.forName(codePageName); + if (codePage == null) { + continue; + } // if + + a_writer.setCodeRangeFlag(codePage.getOsTwoFlag()); + } // for codePageName + } + + private void loadUnicodeRanges(FontFileWriter a_writer) { + String [] unicodeRanges = m_glyph.getHead().getUnicodeRange(); + int i; + for (i = 0; i < unicodeRanges.length; i++) { + if (!TTUnicodeRange.find(unicodeRanges[i])) { + continue; + } // if + + a_writer.addUnicodeRange(TTUnicodeRange.getLastFound()); + } // for i + } + + private void loadGlyphs(FontFileWriter a_writer) throws Exception { + m_nameToIndeces.clear(); + + for (String fileName: getChildFileNames()) { + GlyphFile glyphFile = nameToGlyphFile(fileName); + loadGlyph(glyphFile, glyphFile, a_writer); + } // for + } + + private GlyphFile nameToGlyphFile(String a_fileName) throws FileNotFoundException { + File file = new File(m_dir, a_fileName); + + if (!file.exists()) { + throw new FileNotFoundException(a_fileName); + } // if + + GlyphFile retval = new GlyphFile(file); + + return retval; + } + + /** + * load the glyph into FontFileWriter. + * @param a_fileName + * @param a_writer + * @throws Exception + */ + private void loadGlyph(GlyphFile a_glyphFile, VarStackFrame a_frame, FontFileWriter a_writer) throws Exception { + if (m_nameToIndeces.containsKey(a_glyphFile.getShortFileName())) { + return; + } // if + + /* + if (a_glyphFile.getUnicodeAsLong() == TTUnicodeRange.k_null) { + return; + } // if + */ + + TTGlyph glyph = null; + m_stack.push(a_frame); + + if (a_glyphFile.isSimple()) { + // glyph will be null if it is empty + glyph = a_glyphFile.toSimpleGlyph(); + } else { + glyph = createCompoundGlyph(a_glyphFile, a_writer); + } // if + + m_stack.pop(); + + if (glyph == null && a_glyphFile.isWhiteSpace()) { + glyph = new TTGlyph(); + } // if + + if (glyph == null) { + return; + } // if + + int glyphIndex = a_writer.addGlyph(glyph); + m_nameToIndeces.put(a_glyphFile.getShortFileName(), glyphIndex); + long unicode = a_glyphFile.getUnicodeAsLong(); + + if (unicode != -1 && glyph != null) { + long existingIndex = a_writer.getCharacterMapping(unicode); + if (existingIndex != 0) { + throw new Exception(Long.toHexString(unicode) + " is mapped already."); + } // if + + a_writer.addCharacterMapping(unicode, glyphIndex); + } // if + } + + private TTGlyph createCompoundGlyph(GlyphFile a_glyphFile, + FontFileWriter a_writer) throws Exception + { + TTGlyph retval = new TTGlyph(); + ArrayList locs = new ArrayList<>(); + ArrayList indeces = new ArrayList<>(); + + retval.setSimple(false); + retval.setAdvanceWidth(a_glyphFile.getAdvanceWidth()); + + TTGlyph simple = a_glyphFile.toSimpleGlyph(); + if (simple != null) { + int glyphIndex = a_writer.addGlyph(simple); + + locs.add(new Point(0, 0)); + indeces.add(glyphIndex); + } // if + + XInclude [] includes = a_glyphFile.m_glyph.getBody().getInclude(); + int i; + for (i = 0; i < includes.length; i++) { + EIncludeInvoke include = (EIncludeInvoke) includes[i]; + GlyphFile glyphFile = nameToGlyphFile(include.getHref()); + + // load the glyph included in this one + loadGlyph(glyphFile, include, a_writer); + Integer n = m_nameToIndeces.get(glyphFile.getShortFileName()); + if (n == null) { + continue; + } // if + + indeces.add(n); + XPoint2d pos = include.getInvoke().getInvokePos().getPoint2d(); + locs.add(new Point((int) pos.getX(), (int) pos.getY())); + } // for i + + int flag = TTGlyph.ARG_1_AND_2_ARE_WORDS + | TTGlyph.ARGS_ARE_XY_VALUES + | TTGlyph.ROUND_XY_TO_GRID; + int numOfCompositePoints = 0; + int numOfCompositeContours = 0; + int componentDepth = 0; + + for (int glyfIndex: indeces) { + TTGlyph glyph = a_writer.getGlyph(glyfIndex); + numOfCompositePoints += glyph.getNumOfCompositePoints(); + numOfCompositeContours += glyph.getNumOfCompositeContours(); + if (glyph.getComponentDepth() > componentDepth) { + componentDepth = glyph.getComponentDepth(); + } // if + + retval.addGlyfIndex(glyfIndex); + if (i < indeces.size() - 1) { + retval.addFlag(flag | TTGlyph.MORE_COMPONENTS); + } else { + retval.addFlag(flag); + } // if-else + + Point loc = locs.get(i); + retval.addArg1(loc.x); + retval.addArg2(loc.y); + } // for + + retval.setNumOfCompositePoints(numOfCompositePoints); + retval.setNumOfCompositeContours(numOfCompositeContours); + retval.setComponentDepth(componentDepth + 1); + + return retval; + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/module/VarStack.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/module/VarStack.java new file mode 100644 index 000000000..2f8526487 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/module/VarStack.java @@ -0,0 +1,112 @@ + /* + * $Id: VarStack.java,v 1.1 2004/04/21 10:54:41 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2004, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa.module; + +import java.util.*; + +/** + * @author e.e + */ +public class VarStack { + private static VarStack s_varstack = null; + + public static VarStack getSingletonInstance() { + if (s_varstack == null) + s_varstack = new VarStack(); + + return s_varstack; + } + + // -------------------------------------------------------------- + + private ArrayList m_stack = new ArrayList<>(); + + // -------------------------------------------------------------- + + public void push(VarStackFrame a_frame) { + a_frame.beforePush(); + m_stack.add(a_frame); + } + + public VarStackFrame pop() { + VarStackFrame retval = peek(); + if (retval == null) { + return retval; + } // if + + m_stack.remove(retval); + + return retval; + } + + public VarStackFrame peek() { + if (m_stack.size() <= 0) { + return null; + } // if + + return (VarStackFrame) m_stack.get(m_stack.size() - 1); + } + + public void clear() { + m_stack.clear(); + } + + public int size() { + return m_stack.size(); + } + + /** + * goes through the var stack and returns the variable value + * @param a_name name of the variable + * @return the value of the variable + */ + public double get(String a_name) { + int i; + double retval = 0.0; + + for (i = 0; i < m_stack.size(); i++) { + VarStackFrame frame + = (VarStackFrame) m_stack.get(m_stack.size() - i - 1); + if (!frame.hasVariable(a_name)) { + continue; + } // if + + return frame.getValue(a_name); + } // for i + + return retval; + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/module/VarStackFrame.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/module/VarStackFrame.java new file mode 100644 index 000000000..aa27f9709 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/module/VarStackFrame.java @@ -0,0 +1,53 @@ + /* + * $Id: VarStackFrame.java,v 1.1 2004/04/21 10:55:02 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2004, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa.module; + +/** + * @author e.e + */ +public interface VarStackFrame { + /** + * tests if the variable is declared in this module. + * @param a_name name of the variable + * @return true, if declared; false, otherwise. + */ + boolean hasVariable(String a_name); + double getValue(String a_name); + + /** fired before push by the var stack. + */ + void beforePush(); +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/module/empty.glyph b/trunk/libsrc/ttf/src/org/doubletype/ossa/module/empty.glyph new file mode 100644 index 000000000..6fdefeb4d --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/module/empty.glyph @@ -0,0 +1,21 @@ + + + + + + + Nobody + 2004 + temp + Regular + All rights reserved. + + + + + + + + + + diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/CmapWriter.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/CmapWriter.java new file mode 100644 index 000000000..eb1640bf3 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/CmapWriter.java @@ -0,0 +1,316 @@ +/* + * $Id: CmapWriter.java,v 1.8 2004/01/27 00:35:08 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa.truetype; + +import java.io.*; +import java.util.*; + +/** + * @author e.e + */ +public class CmapWriter extends FontFormatWriter { + final long k_basicLatinStart = 0x20; + final long k_basicLatinEnd = 0x7e; + final long k_tableEnd = 0xffff; + final int k_unmappedChar = 0x0; + + private OS2Writer m_os2; + private List m_unicodes = new ArrayList<>(); + private List m_startCodes = new ArrayList<>(); + private List m_endCodes = new ArrayList<>(); + private Hashtable m_unicode2glyph = new Hashtable<>(); + private List m_unicodeRanges = new ArrayList<>(); + private List m_idDeltas = new ArrayList<>(); + private List m_idRangeOffsets = new ArrayList<>(); + private boolean m_isIncludeVersion0; + private byte [] m_version0; + private byte [] m_version4; + private byte [] m_version12; + + public CmapWriter(OS2Writer a_os2) { + super(); + + m_os2 = a_os2; + m_isIncludeVersion0 = false; + } + + @SuppressWarnings("unchecked") + private void prepare() { + Collections.sort(m_unicodeRanges); + + TTUnicodeRange range = (TTUnicodeRange) m_unicodeRanges.get(0); + m_os2.m_usFirstCharIndex = (int) range.getStartCode(); + m_os2.m_usLastCharIndex = (int) range.getEndCode(); + + int i; + for (i = 0; i < m_unicodeRanges.size(); i++) { + range = m_unicodeRanges.get(i); + + m_startCodes.add(range.getStartCode()); + m_endCodes.add(range.getEndCode()); + m_idDeltas.add(0L); + m_idRangeOffsets.add( + 2L * (m_unicodeRanges.size() - i) + 2L + + 2L * (m_unicodes.size())); + + m_os2.m_usLastCharIndex = (int) range.getEndCode(); + m_os2.setUnicodeRangeFlag(range.getOsTwoFlag()); + + for (long unicode = range.getStartCode(); + unicode <= range.getEndCode(); unicode++) + { + m_unicodes.add(unicode); + } // for unicode + } // for i + + m_startCodes.add(k_tableEnd); + m_endCodes.add(k_tableEnd); + m_idDeltas.add(1L); + m_idRangeOffsets.add(0L); + } + + public void write() throws IOException { + prepare(); + + if (m_isIncludeVersion0) { + storeVersion0(); + } // if + storeVersion4(); + + reset(); + + writeUInt16(0); // table version number + writeUInt16(getNumOfEncoding()); // num of encodings + + if (m_isIncludeVersion0) { + writeUInt16(TTName.k_macintosh); + writeUInt16(TTName.k_macRomanEncode); + writeUInt32(size() + 4 + 8); + } // if + + writeUInt16(TTName.k_microsoft); + writeUInt16(TTName.k_winUnicodeEncode); + int version4Offset = size() + 4; + if (m_isIncludeVersion0) { + version4Offset += m_version0.length; + } // if + writeUInt32(version4Offset); + + if (m_isIncludeVersion0) { + m_buffer.write(m_version0); + } // if + + m_buffer.write(m_version4); + pad(); + } + + private int getNumOfEncoding() { + if (m_isIncludeVersion0) { + return 2; + } // if + + return 1; + } + + public void addUnicodeRange(TTUnicodeRange a_range) { + m_unicodeRanges.add(a_range); + } + + public void addMapping(long a_unicode, long a_glyfIndex) { + m_unicode2glyph.put(a_unicode, a_glyfIndex); + } + + /** + * Find 'glyf' index for the given unicode. + * This method returns 0, if a_key was not found, which will be treated + * as unmapped character. + * @param a_key Long object with unicode value. + * @return 'glyf' index if a_key was found; 0 otherwise. + */ + public long getGlyfIndex(Long a_key) { + long retval = 0; + + if (m_unicode2glyph.containsKey(a_key)) { + retval = m_unicode2glyph.get(a_key); + } // if + + return retval; + } + + private void storeVersion0() throws IOException { + reset(); + writeVersion0(); + m_version0 = toByteArray(); + reset(); + } + + private void storeVersion4() throws IOException { + reset(); + writeVersion4(); + m_version4 = toByteArray(); + reset(); + } + + private void storeVersion12() throws IOException { + reset(); + writeVersion12(); + m_version12 = toByteArray(); + reset(); + } + + protected String getTag() { + return "cmap"; + } + + private void writeVersion0() throws IOException { + writeUInt16(0); + writeUInt16(262); + writeUInt16(0); + int i; + for (i = 0; i < 256; i++) { + if ((i == 0x000) || (i == 0x0008) || (i == 0x001D)) { + writeUInt8((int) getGlyfIndex(TTUnicodeRange.k_null)); // .null + } + else if ((i == 0x0009) || (i == 0x000d)) { + writeUInt8((int) getGlyfIndex(TTUnicodeRange.k_cr)); // CR + } + else { + writeUInt8((int) getGlyfIndex((long) i)); + } // if + } // for i + } + + private void writeVersion4() throws IOException { + int segCount = m_startCodes.size(); + int i; + + // endCount + for (i = 0; i < segCount; i++) { + Long n = (Long) m_endCodes.get(i); + writeUInt16(n.intValue()); + } // for i + + // reserverdPad + writeUInt16(0); + + // startCount + for (i = 0; i < segCount; i++) { + Long n = m_startCodes.get(i); + writeUInt16(n.intValue()); + } // for i + + // idDelta + for (i = 0; i < segCount; i++) { + Long n = m_idDeltas.get(i); + writeInt16(n.intValue()); + } // for i + + // idRangeOffset + for (i = 0; i < segCount; i++) { + Long n = m_idRangeOffsets.get(i); + writeInt16(n.intValue()); + } + + // glyphIdArray 2 bytes each + for (i = 0; i < m_unicodes.size(); i++) { + Long unicode = m_unicodes.get(i); + writeUInt16((int) getGlyfIndex(unicode)); + } // for i + + byte [] bytes = m_bytes.toByteArray(); + + reset(); + + writeUInt16(4); + writeUInt16(bytes.length + 14); + writeUInt16(0); + writeUInt16(segCount * 2); + + int searchRange = getSearchRange(segCount); + writeUInt16(searchRange); + writeUInt16(getEntrySelector(searchRange)); + writeUInt16(getRangeShift(segCount, searchRange)); + m_buffer.write(bytes); + } + + public void writeVersion12() throws IOException { + ArrayList startCharCode = new ArrayList<>(); + ArrayList endCharCode = new ArrayList<>(); + ArrayList startGlyphCode = new ArrayList<>(); + + // TODO: map to real one + startCharCode.add(k_basicLatinStart); + endCharCode.add(k_basicLatinEnd); + startGlyphCode.add(1L); + + long length = 16 + 12 * startCharCode.size(); + + writeFixed32(12.0); + writeUInt32(length); + writeUInt32(0); + writeUInt32(startCharCode.size()); + + int i; + for (i = 0; i < startCharCode.size(); i++) { + writeUInt32(startCharCode.get(i)); + writeUInt32(endCharCode.get(i)); + writeUInt32(startGlyphCode.get(i)); + } // for i + } + + /** + * Used for searchRange + * @param a_value + * @return + */ + private int getSearchRange(int a_value) { + int retval + = (int) Math.pow(2, Math.floor(Math.log(a_value) / Math.log(2))); + return 2 * retval; + } + + private int getEntrySelector(int a_searchRange) { + int retval + = (int) (Math.log(a_searchRange / 2) / Math.log(2)); + return retval; + } + + private int getRangeShift(int a_value, int a_searchRange) { + int retval + = 2 * a_value - a_searchRange; + return retval; + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/FontFileWriter.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/FontFileWriter.java new file mode 100644 index 000000000..97ff35df3 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/FontFileWriter.java @@ -0,0 +1,286 @@ +/* + * $Id: FontFileWriter.java,v 1.15 2004/10/04 02:25:39 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + + +package org.doubletype.ossa.truetype; + +import java.io.*; +import java.util.*; + +/** + * @author e.e + */ +public class FontFileWriter extends FontFormatWriter { + private CmapWriter m_cmap; + private GlyfWriter m_glyf; + private LocaWriter m_loca; + private HeadWriter m_head; + private HdmxWriter m_hdmx; + private HheaWriter m_hhea; + private HmtxWriter m_hmtx; + private MaxpWriter m_maxp; + private NameWriter m_name; + private PostWriter m_post; + private OS2Writer m_os2; + + protected RandomAccessFile m_file; + private ArrayList m_tables = new ArrayList<>(); + + public FontFileWriter(RandomAccessFile a_file) { + super(); + + m_file = a_file; + + m_loca = new LocaWriter(); + m_maxp = new MaxpWriter(); + m_head = new HeadWriter(); + m_hdmx = new HdmxWriter(); + m_os2 = new OS2Writer(m_head); + m_cmap = new CmapWriter(m_os2); + + m_glyf = new GlyfWriter(m_loca, m_maxp, + m_head, m_hdmx); + + m_hhea = new HheaWriter(m_glyf, m_head); + m_hmtx = new HmtxWriter(m_glyf, m_hhea); + m_name = new NameWriter(); + m_post = new PostWriter(); + + // http://www.microsoft.com/typography/otspec/recom.htm + // head, hhea, maxp, OS/2, hmtx, LTSH, VDMX, hdmx, cmap, + // fpgm, prep, cvt, loca, glyf, kern, name, post, gasp, PCLT, DSIG + /* + m_tables.add(m_head); + m_tables.add(m_hhea); + m_tables.add(m_maxp); + m_tables.add(m_os2); + m_tables.add(m_hmtx); + m_tables.add(m_hdmx); + m_tables.add(m_cmap); + m_tables.add(m_loca); + m_tables.add(m_glyf); + m_tables.add(m_name); + m_tables.add(m_post); + */ + + // Verdana has head, hhea, maxp, OS/2, gasp, name, cmap, loca + // LTSH, VDMX, prep, fpgm, cvt, hmtx, hdmx, glyf, post, kern, edt0, DSIG + m_tables.add(m_head); + m_tables.add(m_hhea); + m_tables.add(m_maxp); + m_tables.add(m_os2); + m_tables.add(m_name); + m_tables.add(m_cmap); + m_tables.add(m_loca); + + m_tables.add(m_hmtx); + m_tables.add(m_hdmx); + m_tables.add(m_glyf); + m_tables.add(m_post); + } + + /** + * write TrueType file to the random access file + */ + public void write() throws IOException { + m_cmap.write(); + // hmtx must be written before hhea + m_hmtx.write(); + m_hhea.write(); + + m_glyf.write(); + m_loca.write(); + + m_head.setCheckSumAdjustment(0); + m_head.write(); + m_maxp.write(); // must be written after m_glyf + m_hdmx.write(); + m_name.write(); + m_post.write(); + m_os2.write(); + + writeTableDirectory(); + byte [] tableDir = toByteArray(); + for (FontFormatWriter table: m_tables) { + m_buffer.write(table.toByteArray()); + } // for table + + long checkSum = 0xb1b0afba - (0xffffffff & getCheckSum()); + m_head.setCheckSumAdjustment(checkSum); + m_head.reset(); + m_head.write(); + + reset(); + + m_buffer.write(tableDir); + for (FontFormatWriter table: m_tables) { + m_buffer.write(table.toByteArray()); + } // for table + + m_file.write(toByteArray()); + m_file.close(); + } + + public void setAscent(int a_value) { + m_os2.setTypoAscender(a_value); + m_os2.setCapHeight(a_value); + } + + public void setDescent(int a_value) { + m_os2.setTypoDescender(-a_value); + } + + public void setXHeight(int a_value) { + m_os2.setXHeight(a_value); + } + + public void setLineGap(int a_value) { + m_os2.setTypoLineGap(a_value); + m_hhea.setLineGap(a_value); + } + + public void setFontFamilyName(String a_name) { + m_name.m_familyName = a_name; + } + + public void setCopyrightYear(String a_year) { + m_name.m_year = a_year; + } + + public void setManufacturer(String a_manufacturer) { + m_name.m_manufacturer = a_manufacturer; + } + + public void setFontVersion(String a_version) { + m_name.m_version = a_version; + } + + public void addUnicodeRange(TTUnicodeRange a_range) { + m_cmap.addUnicodeRange(a_range); + } + + /** + * http://www.microsoft.com/typography/otspec/os2.htm + * @param a_codeRange position of the bit. For example, JIS will be 17. + */ + public void setCodeRangeFlag(int a_codeRange) { + m_os2.setCodePageRangeFlag(a_codeRange); + } + + /** + * adds glyph to the 'glyf' subtable. + * @param a_glyph the glyph to be added. + * @return 'glyf' index of the added glyph. + */ + public int addGlyph(TTGlyph a_glyph) { + return m_glyf.add(a_glyph); + } + + public TTGlyph getGlyph(int a_index) { + return m_glyf.getGlyph(a_index); + } + + /** + * adds character mapping to + * @param a_unicode unicode of the character + * @param a_glyfIndex 'glyf' index obtained from #addGlyph + */ + public void addCharacterMapping(long a_unicode, long a_glyfIndex) { + m_cmap.addMapping(a_unicode, a_glyfIndex); + } + + public long getCharacterMapping(long a_unicode) { + return m_cmap.getGlyfIndex(new Long(a_unicode)); + } + + /** + * writes table directory. + * @throws IOException + */ + private void writeTableDirectory() throws IOException { + int headerLength = m_tables.size() * 16 + 16; + int tableOffset = headerLength; + for (FontFormatWriter table: m_tables) { + table.setOffset(tableOffset); + tableOffset += table.size(); + } // for table + + @SuppressWarnings("unchecked") + ArrayList tables = (ArrayList) m_tables.clone(); + Collections.sort(tables, new Comparator() { + public int compare(FontFormatWriter a_lhs, FontFormatWriter a_rhs) { + return a_lhs.getTag().compareTo(a_rhs.getTag()); + } + + public boolean equals(Object a_value) { + return false; + } + }); + + writeFixed32(1.0); + + int numOfTables = tables.size(); + writeUInt16(numOfTables); + int searchRange = getSearchRange(numOfTables); + writeUInt16(searchRange); + int entrySelector = getEntrySelector(numOfTables); + writeUInt16(entrySelector); + writeUInt16(numOfTables * 16 - searchRange); + + for (FontFormatWriter table: tables) { + writeTag(table.getTag()); + writeUInt32(table.getCheckSum()); + writeUInt32(table.getOffset()); + writeUInt32(table.size()); + } // for + + // padding is always 4 zeros + for (int i = 0; i < 4; i++) { + writeUInt8(0); + } // for i + } + + private int getSearchRange(int a_value) { + int retval + = (int) (Math.pow(2, Math.floor(Math.log(a_value) / Math.log(2)))); + return 16 * retval; + } + + private int getEntrySelector(int a_value) { + int retval + = (int) Math.floor(Math.log(a_value) / Math.log(2)); + return retval; + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/FontFormatWriter.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/FontFormatWriter.java new file mode 100644 index 000000000..2d2030cc8 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/FontFormatWriter.java @@ -0,0 +1,173 @@ +/* + * $Id: FontFormatWriter.java,v 1.6 2004/01/28 11:44:08 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa.truetype; + +import java.io.*; +import java.util.*; + +/** + * @author e.e + */ +public class FontFormatWriter { + protected DataOutputStream m_buffer; + protected ByteArrayOutputStream m_bytes; + private int m_offset; + + public FontFormatWriter() { + init(); + } + + protected void init() { + m_bytes = new ByteArrayOutputStream(); + m_buffer = new DataOutputStream(m_bytes); + m_offset = 0; + } + + public void write() throws IOException { + } + + public byte[] toByteArray() { + return m_bytes.toByteArray(); + } + + /** + * Size of buffer in bytes. + * @return size of buffer in bytes. + */ + public int size() { + return m_bytes.size(); + } + + public void reset() { + m_bytes.reset(); + } + + protected void writeFixed32(double a_value) throws IOException { + final int k_denom = 16384; + + short mantissa = (short) Math.floor(a_value); + int fraction = (int) ((a_value - mantissa) * k_denom); + if (fraction > k_denom) { + fraction = 0; + mantissa++; + } // if + + m_buffer.writeShort(mantissa); + m_buffer.writeShort(fraction); + } + + protected void writeUInt16(int a_value) throws IOException { + writeInt16((short) (0xffff & a_value)); + } + + protected void writeInt16(int a_value) throws IOException { + m_buffer.writeShort((short) a_value); + } + + protected void writeFWord(int a_value) throws IOException { + writeInt16(a_value); + } + + protected void writeUFWord(int a_value) throws IOException { + writeUInt16(a_value); + } + + protected void writeUInt32 (long a_value) throws IOException { + writeInt32((int) (0xffffffff & a_value)); + } + + protected void writeInt32(int a_value) throws IOException { + m_buffer.writeInt(a_value); + } + + protected void writeUInt8(int a_byte) throws IOException { + m_buffer.writeByte(a_byte); + } + + protected void writeTag(String a_value) throws IOException { + String s = a_value + " "; + + int i; + for (i = 0; i < 4; i++) { + writeUInt8(s.charAt(i)); + } // for i + } + + protected void writeLongDateTime(Date a_date) throws IOException { + long sec = a_date.getTime() / 1000; + sec += (1970 - 1904) * 365 * 24 * 60 * 60; + m_buffer.writeLong(sec); + } + + protected String getTag() { + throw new RuntimeException("unimplemnted call to getTag"); + } + + protected long getCheckSum() { + long retval = 0; + byte [] bytes = toByteArray(); + + for (int i = 0; i < bytes.length / 4; i++) { + long n = 0; + for (int j = 0; j < 4; j++) { + n += bytes[4 * i + j] << ((4 - j) * 8); + } // for j + retval += n; + } // for i + + return retval; + } + + protected void pad() throws IOException { + int align = 4; + int numOfPad = align - toByteArray().length % align; + if (numOfPad == align) + return; + + int i; + for (i = 0; i < numOfPad; i++) { + writeUInt8(0); + } // for i + } + + public int getOffset() { + return m_offset; + } + + public void setOffset(int a_value) { + m_offset = a_value; + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/GlyfWriter.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/GlyfWriter.java new file mode 100644 index 000000000..8a89e92b1 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/GlyfWriter.java @@ -0,0 +1,203 @@ +/* + * $Id: GlyfWriter.java,v 1.17 2004/09/23 07:47:39 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + + +package org.doubletype.ossa.truetype; + +import java.io.*; +import java.awt.*; +import java.util.*; + +/** + * @author e.e + */ +public class GlyfWriter extends FontFormatWriter { + private ArrayList m_glyphs; + + private LocaWriter m_loca; + private MaxpWriter m_maxp; + private HeadWriter m_head; + private HdmxWriter m_hdmx; + + public GlyfWriter(LocaWriter a_loca, MaxpWriter a_maxp, + HeadWriter a_head, HdmxWriter a_hdmx) { + super(); + + m_loca = a_loca; + m_maxp = a_maxp; + m_head = a_head; + m_hdmx = a_hdmx; + m_glyphs = new ArrayList<>(); + } + + public void write() throws IOException { + m_hdmx.setNumGlyphs(numOfGlyph()); + m_maxp.setNumGlyphs(numOfGlyph()); + m_loca.m_offsets.clear(); + + for (int i = 0; i < m_glyphs.size(); i++) { + writeGlyph(m_glyphs.get(i)); + m_hdmx.updatePixelWidth(i, m_glyphs.get(i)); + } // for i + + m_loca.m_offsets.add(size()); + } + + public int add(TTGlyph a_glyph) { + m_head.updateMax(a_glyph.getMax()); + m_head.updateMin(a_glyph.getMin()); + + m_glyphs.add(a_glyph); + return m_glyphs.size() - 1; + } + + public int numOfGlyph() { + return m_glyphs.size(); + } + + public TTGlyph getGlyph(int a_index) { + return m_glyphs.get(a_index); + } + + private void writeGlyph(TTGlyph a_glyph) throws IOException { + m_loca.m_offsets.add(size()); + + if (a_glyph == null) { + return; + } // if + + if (a_glyph.isSimple()) { + writeSimpleGlyph(a_glyph); + } else { + writeCompoundGlyph(a_glyph); + } // if-else + + pad(); + } + + /** + * @param a_glyph + * @throws IOException + */ + private void writeSimpleGlyph(TTGlyph a_glyph) throws IOException { + if (a_glyph.getNumOfContours() == 0) { + return; + } // if + + m_maxp.updateNumOfContours(a_glyph.getNumOfContours()); + writeInt16(a_glyph.getNumOfContours()); + writeMinMax(a_glyph); + + int i; + for (i = 0; i < a_glyph.getNumOfContours(); i++) { + writeUInt16(a_glyph.getEndPoint(i)); + } // for i + + int numOfInst = a_glyph.getNumOfInstructions(); + m_maxp.updateSizeOfInstructions(numOfInst); + + writeUInt16(numOfInst); + for (i = 0; i < numOfInst; i++) { + writeUInt8(a_glyph.getInstruction(i)); + } // for i + + for (i = 0; i < a_glyph.getNumOfFlags(); i++) { + int flag = a_glyph.getFlag(i); + writeUInt8(flag); + } // for i + + // update num of points + m_maxp.updateNumOfPoints(a_glyph.getNumOfPoints()); + + int lastX = 0; + for (i = 0; i < a_glyph.getNumOfPoints(); i++) { + Point point = a_glyph.getPoint(i); + + writeInt16(point.x - lastX); + lastX = point.x; + } // for i + + int lastY = 0; + for (i = 0; i < a_glyph.getNumOfPoints(); i++) { + Point point = a_glyph.getPoint(i); + + writeInt16(point.y - lastY); + lastY = point.y; + } // for i + } + + /** + * @param a_glyph + * @throws IOException + */ + private void writeCompoundGlyph(TTGlyph a_glyph) throws IOException { + int i; + + m_maxp.updateNumOfCompositePoints(a_glyph.getNumOfCompositePoints()); + m_maxp.updateNumOfCompositeContours(a_glyph.getNumOfCompositeContours()); + + writeInt16(-1); + writeMinMax(a_glyph); + + int numOfGlyphs = a_glyph.getNumOfFlags(); + m_maxp.updateNumOfComponentElements(numOfGlyphs); + m_maxp.updateComponentDepth(a_glyph.getComponentDepth()); + + for (i = 0; i < numOfGlyphs; i++) { + writeUInt16(a_glyph.getFlag(i)); + writeUInt16(a_glyph.getGlyfIndex(i)); + writeInt16(a_glyph.getArg1(i)); + writeInt16(a_glyph.getArg2(i)); + } // for i + } + + /** + * @param a_glyph + * @throws IOException + */ + private void writeMinMax(TTGlyph a_glyph) throws IOException { + Point min = a_glyph.getMin(); + Point max = a_glyph.getMax(); + + writeFWord(min.x); + writeFWord(min.y); + writeFWord(max.x); + writeFWord(max.y); + } + + protected String getTag() { + return "glyf"; + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/HdmxWriter.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/HdmxWriter.java new file mode 100644 index 000000000..1ba5a6c3f --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/HdmxWriter.java @@ -0,0 +1,117 @@ +/* + * $Copyright: copyright (c) 2003-2008, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + + +package org.doubletype.ossa.truetype; + +import java.io.*; +import java.util.*; + +/** + * HtmxWriter depends on GlyfWriter. + * + * @author e.e + */ +public class HdmxWriter extends FontFormatWriter { + static public int getNumOfPixelSizes() { + return TTPixelSize.getList().size(); + } + + static public ArrayList getPixelSizes() { + return TTPixelSize.getList(); + } + + private int m_numGlyphs = 98; // set by GlyfWriter + + public HdmxWriter() { + super(); + } + + /** set the number of glyphs in the font */ + public void setNumGlyphs(int a_value) { + m_numGlyphs = a_value; + + for (TTPixelSize pixelSize: getPixelSizes()) { + pixelSize.setPixelWidthsSize(a_value); + } // for pixelSize + } + + public void updatePixelWidth(int a_glyphIndex, TTGlyph a_glyph) { + double advanceWidth = a_glyph.getAdvanceWidth(); + double em = TTPixelSize.getEm(); + + for (TTPixelSize pixelSize: TTPixelSize.getList()) { + int width = (int) Math.round(((double) pixelSize.getPixel() * advanceWidth) / em); + pixelSize.setPixelWidth(a_glyphIndex, width); + } // pixelSize + } + + /** + * writes htmx record. + * The size of a device record is calculated to align it to 32bit boundary. + */ + public void write() throws IOException { + int numOfPads = 4 - ((m_numGlyphs + 2) % 4); + if (numOfPads == 4) { + numOfPads = 0; + } // if + int size = m_numGlyphs + 2 + numOfPads; // 2 comes from the ppem and max + + // format version number + writeInt16(0); + + // number of device records + writeInt16(getNumOfPixelSizes()); + //System.out.printf("num of pixel sizes %d\n", getNumOfPixelSizes()); + // size of device record + writeInt32(size); + //System.out.printf("num of glyphs %d\n", m_numGlyphs); + for (TTPixelSize pixelSize: getPixelSizes()) { + writeUInt8(pixelSize.getPixel()); + writeUInt8(pixelSize.getMaxPixelWidth()); + for (int pixelWidth: pixelSize.getPixelWidths()) { + writeUInt8(pixelWidth); + } // for pixelWidth + + for (int j = 0; j < numOfPads; j++) { + writeUInt8(0); + } // for j + } // for pixelSize + + pad(); + } + + protected String getTag() { + return "hdmx"; + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/HeadWriter.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/HeadWriter.java new file mode 100644 index 000000000..3b23d4e49 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/HeadWriter.java @@ -0,0 +1,156 @@ +/* + * $Id: HeadWriter.java,v 1.7 2004/09/26 09:15:48 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + + +package org.doubletype.ossa.truetype; + +import java.io.*; +import java.util.*; +import java.awt.*; + +/** + * @author e.e + */ +public class HeadWriter extends FontFormatWriter { + static public final int k_yZeroIsBaseLine = 0x1; // bit 0 + static public final int k_xLeftMostBlackIsLsb = 0x2; // bit 1 + static public final int k_scaledPointDiffer = 0x4; // bit 2 + static public final int k_useIntegerScaling = 0x8; // bit 3 + + // used by microsoft + static public final int k_scaleLinear = 0x10; + + // for vertical fonts + static public final int k_xZeroIsBaseLine = 0x20; + // 0x40 + static public final int k_linguisticRendering = 0x80; + static public final int k_defaultMetamorphosis = 0x100; + static public final int k_rightToLeft = 0x200; + static public final int k_indicRearrangement = 0x400; + + + private final long k_magicNumber = 0x5f0f3cf5; + + private long m_checkSumAdjustment = 0; + private Point m_min = new Point(0, 0); + private Point m_max = new Point(0, 0); + + public HeadWriter() { + super(); + } + + void setCheckSumAdjustment(long a_value) { + m_checkSumAdjustment = a_value; + } + + public Point getMin() { + return m_min; + } + + public Point getMax() { + return m_max; + } + + public void updateMin(Point a_value) { + if (a_value.x < m_min.x) { + m_min.x = a_value.x; + } // if + + if (a_value.y < m_min.y) { + m_min.y = a_value.y; + } // if + } + + public void updateMax(Point a_value) { + if (a_value.x > m_max.x) { + m_max.x = a_value.x; + } // if + + if (a_value.y > m_max.y) { + m_max.y = a_value.y; + } // if + } + + public void write() throws IOException { + // table version number + writeFixed32(1.0); + + // fontRevision + writeFixed32(1.0); + + writeUInt32(m_checkSumAdjustment); + writeUInt32(k_magicNumber); + + // LSB is the distance from 0, 0 to the left of the glyph bounds. + // flags + writeUInt16(k_yZeroIsBaseLine + | k_xLeftMostBlackIsLsb + | k_scaledPointDiffer);; + + // unitsPerEm + writeUInt16(1024); + + // created, modified + writeLongDateTime(new Date()); + writeLongDateTime(new Date()); + + writeFWord(m_min.x); + writeFWord(m_min.y); + writeFWord(m_max.x); + writeFWord(m_max.y); + + // macStyle + writeUInt16(0); + + // lowestRecPPEM + writeUInt16(11); + + // font direction hint + // 2, for strongly left to right + // but also contains neutrals + writeInt16(2); + + // indexToLocFormat. 1, for long + writeInt16(1); + + // glyfDataFormat + writeInt16(0); + pad(); + } + + protected String getTag() { + return "head"; + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/HheaWriter.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/HheaWriter.java new file mode 100644 index 000000000..7c75f8748 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/HheaWriter.java @@ -0,0 +1,108 @@ +/* + * $Id: HheaWriter.java,v 1.5 2004/09/26 09:15:48 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + + +package org.doubletype.ossa.truetype; + +import java.io.*; + +/** + * HheaWriter depends on HtmxWriter. + * @author e.e + */ +public class HheaWriter extends FontFormatWriter { + private GlyfWriter m_glyf; + private HeadWriter m_head; + + private int m_lineGap = 0; + private int m_maxAdvanceWidth = 0; + private int m_minRightSideBearing = 0; + + public HheaWriter(GlyfWriter a_glyf, HeadWriter a_head) { + super(); + + m_glyf = a_glyf; + m_head = a_head; + } + + public void setLineGap(int a_value) { + m_lineGap = a_value; + } + + public void setMaxAdvanceWidth(int a_value) { + m_maxAdvanceWidth = a_value; + } + + public void setMinRightSideBearing(int a_value) { + m_minRightSideBearing = a_value; + } + + public void write() throws IOException { + // table version number + writeFixed32(1.0); + + writeFWord(m_head.getMax().y); + writeFWord(m_head.getMin().y); + writeFWord(m_lineGap); + writeUFWord(m_maxAdvanceWidth); + + int minLeftSideBearing = m_head.getMin().x; + writeFWord(minLeftSideBearing); + writeFWord(m_minRightSideBearing); + + int xMaxExtent = m_head.getMax().x - m_head.getMin().x; + writeFWord(xMaxExtent); + + // caratSlopeRise + writeInt16(1); + writeInt16(0); + + // reserved + for (int i = 0; i < 5; i++) { + writeInt16(0); + } // for i + + writeInt16(0); + + int numOfHMetrics = m_glyf.numOfGlyph(); + writeUInt16(numOfHMetrics); + + pad(); + } + + protected String getTag() { + return "hhea"; + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/HmtxWriter.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/HmtxWriter.java new file mode 100644 index 000000000..f8a487329 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/HmtxWriter.java @@ -0,0 +1,89 @@ +/* + * $Id: HmtxWriter.java,v 1.10 2004/10/04 02:25:39 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + + +package org.doubletype.ossa.truetype; + +import java.io.*; + +/** + * HtmxWriter depends on GlyfWriter. + * + * @author e.e + */ +public class HmtxWriter extends FontFormatWriter { + HheaWriter m_hhea; + GlyfWriter m_glyf; + + public HmtxWriter(GlyfWriter a_glyf, HheaWriter a_hhea) { + super(); + + m_hhea = a_hhea; + m_glyf = a_glyf; + } + + public void write() throws IOException { + int i; + + TTGlyph glyphZero = m_glyf.getGlyph(0); + int maxWidth = glyphZero.getAdvanceWidth(); + int minRightSideBearing = glyphZero.getRightSideBearing(); + for (i = 0; i < m_glyf.numOfGlyph(); i++) { + TTGlyph glyph = m_glyf.getGlyph(i); + + if (glyph.getAdvanceWidth() > maxWidth) { + maxWidth = glyph.getAdvanceWidth(); + } // if + + if (glyph.getRightSideBearing() < minRightSideBearing) { + minRightSideBearing = glyph.getRightSideBearing(); + } // if + + writeUFWord(glyph.getAdvanceWidth()); + writeFWord(glyph.getLeftSideBearing()); + } // for i + + writeFWord(0); + + m_hhea.setMaxAdvanceWidth(maxWidth); + m_hhea.setMinRightSideBearing(minRightSideBearing); + + pad(); + } + + protected String getTag() { + return "hmtx"; + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/LocaWriter.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/LocaWriter.java new file mode 100644 index 000000000..4a2056d0b --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/LocaWriter.java @@ -0,0 +1,67 @@ +/* + * $Id: LocaWriter.java,v 1.3 2004/01/15 07:06:27 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + + +package org.doubletype.ossa.truetype; + +import java.io.*; +import java.util.*; + +/** + * @author e.e + */ +public class LocaWriter extends FontFormatWriter { + public ArrayList m_offsets = new ArrayList<>(); + + public LocaWriter() { + super(); + } + + public void write() throws IOException { + // assume glyf table is already written, + // and offsets are stored in m_offsets + + int i; + for (i = 0; i < m_offsets.size(); i++) { + writeUInt32(m_offsets.get(i)); + } // for i + + pad(); + } + + protected String getTag() { + return "loca"; + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/MaxpWriter.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/MaxpWriter.java new file mode 100644 index 000000000..16880ab29 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/MaxpWriter.java @@ -0,0 +1,137 @@ +/* + * $Id: MaxpWriter.java,v 1.11 2004/06/27 07:26:46 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + + +package org.doubletype.ossa.truetype; + +import java.io.*; + +/** + * @author e.e + */ +public class MaxpWriter extends FontFormatWriter { + private int m_numGlyphs = 98; // set by GlyfWriter + private int m_maxPoints = 0; + private int m_maxContours = 0; + private int m_maxCompositePoints = 0; + private int m_maxCompositeContours = 0; + private int m_maxZones = 2; + private int m_maxTwilightPoints = 128; + private int m_maxStorage = 64; + private int m_maxFunctionDefs = 128; + private int m_maxInstructionDefs = 128; + private int m_maxStackElements = 128; + private int m_maxSizeOfInstructions = 128; + private int m_maxComponentElements = 128; + private int m_maxComponentDepth = 0; + + public MaxpWriter() { + super(); + } + + public void write() throws IOException { + writeFixed32(1.0); + writeUInt16(m_numGlyphs); + writeUInt16(m_maxPoints); + writeUInt16(m_maxContours); + writeUInt16(m_maxCompositePoints); + writeUInt16(m_maxCompositeContours); + writeUInt16(m_maxZones); + writeUInt16(m_maxTwilightPoints); + writeUInt16(m_maxStorage); + writeUInt16(m_maxFunctionDefs); + writeUInt16(m_maxInstructionDefs); + writeUInt16(m_maxStackElements); + writeUInt16(m_maxSizeOfInstructions); + writeUInt16(m_maxComponentElements); + writeUInt16(m_maxComponentDepth); + pad(); + } + + protected String getTag() { + return "maxp"; + } + + /** set the number of glyphs in the font */ + public void setNumGlyphs(int a_value) { + m_numGlyphs = a_value; + } + + /** update points in non-compound glyph */ + public void updateNumOfPoints(int a_value) { + if (a_value > m_maxPoints) { + m_maxPoints = a_value; + } // if + } + + /** update points in non-compound glyph */ + public void updateNumOfContours(int a_value) { + if (a_value > m_maxContours) { + m_maxContours = a_value; + } // if + } + + public void updateNumOfCompositePoints(int a_value) { + if (a_value > m_maxCompositePoints) { + m_maxCompositePoints = a_value; + } // if + } + + public void updateNumOfCompositeContours(int a_value) { + if (a_value > m_maxCompositeContours) { + m_maxCompositeContours = a_value; + } // if + } + + /** update byte count for glyph instructions */ + public void updateSizeOfInstructions(int a_value) { + if (a_value > m_maxSizeOfInstructions) { + m_maxSizeOfInstructions = a_value; + } // if + } + + public void updateNumOfComponentElements(int a_value) { + if (a_value > m_maxComponentElements) { + m_maxComponentElements = a_value; + } // if + } + + public void updateComponentDepth(int a_value) { + if (a_value > m_maxComponentDepth) { + m_maxComponentDepth = a_value; + } // if + } + +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/NameWriter.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/NameWriter.java new file mode 100644 index 000000000..37641a200 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/NameWriter.java @@ -0,0 +1,183 @@ +/* + * $Id: NameWriter.java,v 1.9 2004/06/16 07:02:52 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + + +package org.doubletype.ossa.truetype; + +import java.io.*; +import java.util.*; + +/** + * @author e.e + */ +public class NameWriter extends FontFormatWriter { + public static final String k_regular = "Regular"; + private static final String k_utf16be = "UTF-16BE"; + private static final String k_iso8859_1 = "ISO-8859-1"; + + String m_copyright = "\u00A9 Copyright"; + String m_familyName = "Temp"; + String m_subFamilyName = k_regular; + String m_unique = "eed3si9n: Temp Regular: 2003"; + String m_fullFontName = "Temp"; + String m_version = "0.00"; + String m_psName = "Temp"; + String m_tradeMark = ""; + String m_manufacturer = "eed3si9n"; + String m_year = "2004"; + String m_sample = "The quick brown fox jumps over the lazy dog."; + + private ArrayList m_names = new ArrayList<>(); + + public NameWriter() { + super(); + } + + private void prepare() { + m_copyright = "\u00A9 Copyright " + + m_year + + ", " + + m_manufacturer + + "."; + m_unique = "dtype: " + + m_manufacturer + ": " + + m_familyName + " " + + m_subFamilyName + ": " + + "Version " + m_version + ": " + + m_year; + m_fullFontName = m_familyName; + m_psName = m_fullFontName; + + if (m_tradeMark.length() == 0) { + m_tradeMark = "n/a"; + } // if + + m_names.clear(); + addNames(); + } + + private void addNames() { + addMacintoshRomanEnglish(0, m_copyright); + addMacintoshRomanEnglish(1, m_familyName); + addMacintoshRomanEnglish(2, m_subFamilyName); + addMacintoshRomanEnglish(3, m_unique); + addMacintoshRomanEnglish(4, m_fullFontName); + addMacintoshRomanEnglish(5, "Version " + m_version); + addMacintoshRomanEnglish(6, m_psName); + addMacintoshRomanEnglish(7, m_tradeMark); + addMacintoshRomanEnglish(8, m_manufacturer); + + addMicrosoftUnicodeEnglish(0, m_copyright); + addMicrosoftUnicodeEnglish(1, m_familyName); + addMicrosoftUnicodeEnglish(2, m_subFamilyName); + addMicrosoftUnicodeEnglish(3, m_unique); + addMicrosoftUnicodeEnglish(4, m_fullFontName); + addMicrosoftUnicodeEnglish(5, "Version " + m_version); + addMicrosoftUnicodeEnglish(6, m_psName); + addMicrosoftUnicodeEnglish(7, m_tradeMark); + addMicrosoftUnicodeEnglish(8, m_manufacturer); + // addMicrosoftUnicodeEnglish(19, m_sample); + } + + private void addMacintoshRomanEnglish(int a_nameId, String a_value) { + try { + add(TTName.k_macintosh, + TTName.k_macRomanEncode, + TTName.k_macEnglishLang, + a_nameId, + a_value.getBytes(k_iso8859_1)); + } + catch (IOException e) { + e.printStackTrace(); + } // try-catch + } + + private void addMicrosoftUnicodeEnglish(int a_nameId, String a_value) { + try { + add(TTName.k_microsoft, + TTName.k_winUnicodeEncode, + TTName.k_winEnglishLang, + a_nameId, + a_value.getBytes(k_utf16be)); + } + catch (IOException e) { + e.printStackTrace(); + } + } + + private void add(int a_platformId, int a_encodingId, int a_languageId, + int a_nameId, byte a_bytes[]) { + TTName name = new TTName(a_platformId, + a_encodingId, + a_languageId, + a_nameId, + a_bytes); + m_names.add(name); + } + + public void write() throws IOException { + prepare(); + + // table version number + writeUInt16(0); + + // number of name records + writeUInt16(m_names.size()); + + // Offset to start of string storage (from start of table). + writeUInt16(12 * m_names.size() + 6); + + int offset = 0; + for (TTName name: m_names) { + writeUInt16(name.getPlatformId()); + writeUInt16(name.getEncodingId()); + writeUInt16(name.getLanguageId()); + writeUInt16(name.getNameId()); + writeUInt16(name.getStringLength()); + writeUInt16(offset); + offset += name.getStringLength(); + } // for i + + for (TTName name: m_names) { + m_buffer.write(name.getBytes()); + } // for i + + pad(); + } + + protected String getTag() { + return "name"; + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/OS2Writer.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/OS2Writer.java new file mode 100644 index 000000000..54cf6a398 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/OS2Writer.java @@ -0,0 +1,242 @@ +/* + * $Id: OS2Writer.java,v 1.11 2004/10/04 02:25:39 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + + +package org.doubletype.ossa.truetype; + +import java.io.*; + +/** + * @author e.e + */ +public class OS2Writer extends FontFormatWriter { + final int FW_THIN = 100; + final int FW_EXTRALIGHT = 200; + final int FW_LIGHT = 300; + final int FW_NORMAL = 400; + final int FW_MEDIUM = 500; + final int FW_SEMIBOLD = 600; + final int FW_BOLD = 700; + final int FW_EXTRABOLD = 800; + final int FW_BLACK = 900; + + final int FWIDTH_NORMAL = 5; + + final int k_editableEmbedding = 0x0008; + + final int k_sansSerif = 0x0800; + + // unicode + final int k_basicLatin = 0x0001; + final int k_latin1Supplement = 0x0002; + + final int k_regular = 0x40; + final int k_basicLatinStart = 0x0020; + final int k_basciLatinEnd = 0x007e; + + private HeadWriter m_head; + + int m_xAvgCharWidth = 512; + int m_usWeightClass = FW_NORMAL; + int m_usWidthClass = FWIDTH_NORMAL; + int m_fsType = 0; + int m_ySubscriptXSize = 128; + int m_ySubscriptYSize = 128; + int m_ySubscriptXOffset = 0; + int m_ySubscriptYOffset = -64; + int m_ySuperscriptXSize = 128; + int m_ySuperscriptYSize = 128; + int m_ySuperscriptXOffset = 0; + int m_ySuperscriptYOffset = 64; + int m_yStrikeoutSize = 51; + int m_yStrikeoutPosition = 512; + int m_sFamilyClass = k_sansSerif; + + long m_ulUnicodeRange1 = k_basicLatin | k_latin1Supplement; + long m_ulUnicodeRange2 = 0; + long m_ulUnicodeRange3 = 0; + long m_ulUnicodeRange4 = 0; + String m_vendId = "dtyp"; + int m_fsSelection = k_regular; + int m_usFirstCharIndex = k_basicLatinStart; + int m_usLastCharIndex = k_basciLatinEnd; + private int m_sTypoAscender = 1024; + private int m_sTypoDescender = 0; + private int m_sTypoLineGap = 0; + private int m_usWinAscent = 1024; + private int m_usWinDescent = 0; + long m_ulCodePageRange1 = 0; + long m_ulCodePageRange2 = 0; + private int m_sxHeight = 512; + private int m_sCapHeight = 1024; + int m_usDefaultChar = 0x0; + int m_usBreakChar = 0x20; + int m_usMaxContext = 1; + + public OS2Writer(HeadWriter a_head) { + super(); + + m_head = a_head; + } + + public void setCapHeight(int a_value) { + m_sCapHeight = a_value; + } + + public void setXHeight(int a_value) { + m_sxHeight = a_value; + } + + public void setTypoAscender(int a_value) { + m_sTypoAscender = a_value; + } + + public void setTypoDescender(int a_value) { + m_sTypoDescender = a_value; + } + + public void setTypoLineGap(int a_value) { + m_sTypoLineGap = a_value; + } + + public void setUnicodeRangeFlag(int a_pos) { + int which = a_pos / 32; + int where = a_pos % 32; + long what = 0x1 << where; + + switch (which) { + case 0: { + m_ulUnicodeRange1 |= what; + } break; + + case 1: { + m_ulUnicodeRange2 |= what; + } break; + + case 2: { + m_ulUnicodeRange3 |= what; + } break; + + case 3: { + m_ulUnicodeRange4 |= what; + } break; + } // switch + } + + public void setCodePageRangeFlag(int a_pos) { + int which = a_pos / 32; + int where = a_pos % 32; + long what = 0x1 << where; + + switch (which) { + case 0: { + m_ulCodePageRange1 |= what; + } break; + + case 1: { + m_ulCodePageRange2 |= what; + } break; + } // switch + } + + public void write() throws IOException { + m_usWinAscent = m_head.getMax().y; + m_usWinDescent = 0; + if (m_head.getMin().y < 0) { + m_usWinDescent = -m_head.getMin().y; + } // if + + // table version number + writeUInt16(0x02); + + writeInt16(m_xAvgCharWidth); + writeUInt16(m_usWeightClass); + writeUInt16(m_usWidthClass); + writeInt16(m_fsType); + writeInt16(m_ySubscriptXSize); + writeInt16(m_ySubscriptYSize); + writeInt16(m_ySubscriptXOffset); + writeInt16(m_ySubscriptYOffset); + writeInt16(m_ySuperscriptXSize); + writeInt16(m_ySuperscriptYSize); + writeInt16(m_ySuperscriptXOffset); + writeInt16(m_ySuperscriptYOffset); + writeInt16(m_yStrikeoutSize); + writeInt16(m_yStrikeoutPosition); + writeInt16(m_sFamilyClass); + + writePanose(); + + writeUInt32(m_ulUnicodeRange1); + writeUInt32(m_ulUnicodeRange2); + writeUInt32(m_ulUnicodeRange3); + writeUInt32(m_ulUnicodeRange4); + writeTag(m_vendId); + writeUInt16(m_fsSelection); + writeUInt16(m_usFirstCharIndex); + writeUInt16(m_usLastCharIndex); + writeUInt16(m_sTypoAscender); + writeUInt16(m_sTypoDescender); + writeUInt16(m_sTypoLineGap); + writeUInt16(m_usWinAscent); + writeUInt16(m_usWinDescent); + writeUInt32(m_ulCodePageRange1); + writeUInt32(m_ulCodePageRange2); + writeInt16(m_sxHeight); + writeInt16(m_sCapHeight); + writeUInt16(m_usDefaultChar); + writeUInt16(m_usBreakChar); + writeUInt16(m_usMaxContext); + + pad(); + } + + private void writePanose() throws IOException { + writeUInt8(0); // family + writeUInt8(0); // serif + writeUInt8(0); // weight + writeUInt8(0); // proportion + writeUInt8(0); // contrast + writeUInt8(0); // stroke + writeUInt8(0); // arm style + writeUInt8(0); // letterform + writeUInt8(0); // midline + writeUInt8(0); // x-height + } + + protected String getTag() { + return "OS/2 "; + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/PostWriter.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/PostWriter.java new file mode 100644 index 000000000..ecd99a16b --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/PostWriter.java @@ -0,0 +1,76 @@ +/* + * $Id: PostWriter.java,v 1.3 2004/01/11 13:14:45 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + + +package org.doubletype.ossa.truetype; + +import java.io.*; + +/** + * @author e.e + */ +public class PostWriter extends FontFormatWriter { + boolean m_isMonospaced = false; + + public PostWriter() { + super(); + } + + public void write() throws IOException { + // table version number + writeFixed32(1.0); + writeFixed32(10.0); // italic angle + writeFWord(0); // underline pos + writeFWord(60); // underline thickness + + if (m_isMonospaced) { + writeUInt32(1); // fixed pitch + } else { + writeUInt32(0); + } // if + + // vm memory stuff + writeUInt32(0); + writeUInt32(0); + writeUInt32(0); + writeUInt32(0); + + pad(); + } + + protected String getTag() { + return "post"; + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/TTCodePage.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/TTCodePage.java new file mode 100644 index 000000000..ccf0398a0 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/TTCodePage.java @@ -0,0 +1,189 @@ +/* + * $Id: TTCodePage.java,v 1.3 2004/05/16 12:59:07 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003-2004, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa.truetype; + +import java.util.*; +import java.nio.charset.*; + +/** + * @author e.e + */ +public class TTCodePage { + static public TTCodePage US_ASCII = new TTCodePage("US-ASCII", + "US-ASCII", + 64); + static public TTCodePage Latin_1 = new TTCodePage("windows-1252", + "Latin 1 windows-1252", + 0); + static private boolean s_isInitialized = false; + static private ArrayList s_list = new ArrayList<>(); + + static public String [] getNames() { + initList(); + String [] retval = new String[s_list.size()]; + int i; + for (i = 0; i < s_list.size(); i++) { + TTCodePage codePage = (TTCodePage) s_list.get(i); + retval[i] = codePage.getName(); + } // for i + + return retval; + } + + static public TTCodePage forName(String a_name) { + initList(); + + TTCodePage retval = null; + for (TTCodePage codePage: s_list) { + if (codePage.getName().equals(a_name)) { + return codePage; + } + } // for + + for (TTCodePage codePage: s_list) { + if (codePage.getCharset() == null) { + continue; + } // if + + if (codePage.getCharset().name().equals(a_name)) { + return codePage; + } + } // for + + return retval; + } + + static private void initList() { + if (s_isInitialized) + return; + + s_isInitialized = true; + + s_list.add(US_ASCII); + s_list.add(Latin_1); + s_list.add(new TTCodePage("ISO-2022-JP", + "Japan-JIS", + 17)); + s_list.add(new TTCodePage("windows-1250", + "Latin 2: Eastern Europe windows-1250", + 1)); + s_list.add(new TTCodePage("windows-1251", + "Cyrillic windows-1251", + 2)); + s_list.add(new TTCodePage("windows-1253", + "Greek windows-1253", + 3)); + s_list.add(new TTCodePage("windows-1254", + "Turkish windows-1254", + 4)); + s_list.add(new TTCodePage("windows-1258", + "Vietnamese windows-1258", + 8)); + + + // extended + s_list.add(new TTCodePage("windows-1255", + "Hebrew windows-1255", + 5)); + s_list.add(new TTCodePage("windows-1256", + "Arabic windows-1256", + 6)); + s_list.add(new TTCodePage("windows-1257", + "Windows Baltic", + 7)); + + // TODO: 16 Thai 874 + s_list.add(new TTCodePage( + "Thai windows-874", + 16)); + + s_list.add(new TTCodePage("x-mswin-936", + "Chinese: Simplified", + 18)); + + // TODO: 19 Korean Wansung + s_list.add(new TTCodePage( + "Korean Wansung", + 19)); + + s_list.add(new TTCodePage("x-windows-950", + "Chinese: Traditional", + 20)); + } + + + private String m_name; + + /** http://www.microsoft.com/typography/otspec/os2.htm + */ + private int m_osTwoFlag = 0; + private Charset m_charset = null; + + public TTCodePage(String a_charsetName, String a_name, + int a_osTwoFlag) + { + if (Charset.isSupported(a_charsetName)) { + m_charset = Charset.forName(a_charsetName); + } // if + + m_name = a_name; + m_osTwoFlag = a_osTwoFlag; + } + + public TTCodePage(String a_name, + int a_osTwoFlag) + { + m_name = a_name; + m_osTwoFlag = a_osTwoFlag; + } + + public String toString() { + return m_name; + } + + public String getName() { + return m_name; + } + + + public Charset getCharset() { + return m_charset; + } + + public int getOsTwoFlag() { + return m_osTwoFlag; + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/TTGlyph.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/TTGlyph.java new file mode 100644 index 000000000..de32707b3 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/TTGlyph.java @@ -0,0 +1,391 @@ +/* + * $Copyright: copyright (c) 2003-2008, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa.truetype; + +import java.awt.*; +import java.util.*; + +/** + * @author e.e + */ +public class TTGlyph { + // -------------------------------------------------------------- + public static final int k_onCurve = 0x1; + + public static final int ARG_1_AND_2_ARE_WORDS = 0x1; + public static final int ARGS_ARE_XY_VALUES = 0x2; + public static final int ROUND_XY_TO_GRID = 0x4; + public static final int WE_HAVE_A_SCALE = 0x8; + // 0x10 is obsolete + public static final int MORE_COMPONENTS = 0x20; + public static final int WE_HAVE_AN_X_AND_Y_SCALE = 0x40; + public static final int WE_HAVE_A_TWO_BY_TWO = 0x80; + public static final int WE_HAVE_INSTRUCTIONS = 0x100; + public static final int USE_MY_METRICS = 0x200; + public static final int OVERLAP_COMPOUND = 0x400; + + /** Move Direct Absolute Point - do not round */ + public static final int MDAP0 = 0x2E; + + /** Move Direct Absolute Point - round the value */ + public static final int MDAP1 = 0x2F; + + /** Interpolate Untouched Points through the outline - y-direction */ + public static final int IUP0 = 0x30; + + /** Interpolate Untouched Points through the outline - x-direction */ + public static final int IUP1 = 0x31; + + /** push one byte */ + public static final int PUSHB000 = 0xB0; + + /** push two bytes */ + public static final int PUSHB001 = 0xB1; + + /** push three bytes */ + public static final int PUSHB010 = 0xB2; + public static final int PUSHB011 = 0xB3; + public static final int PUSHB100 = 0xB4; + public static final int PUSHB101 = 0xB5; + public static final int PUSHB110 = 0xB6; + public static final int PUSHB111 = 0xB7; + + /** set vector to y-axis. */ + public static final int SVTCA0 = 0x00; + + /** set vector to x-axis. */ + public static final int SVTCA1 = 0x01; + public static final int SPVFS = 0x0A; // set projection vector + public static final int SFVFS = 0x0B; // set freedom vector + public static final int SFVTPV = 0x0E; + public static final int DELTAP1 = 0x5D; + public static final int DELTAP2 = 0x71; + public static final int DELTAP3 = 0x72; + + /** set delta base */ + public static final int SDB = 0x5E; + + // -------------------------------------------------------------- + + /** + * converts double into F2Dot14, 16 bit fixed point format. + * @param a_value + * @return + */ + public static int toF2Dot14(double a_value) { + int retval = 0; + + if (a_value >= 2.0 || a_value < -2.0) { + throw new RuntimeException(Double.toString(a_value) + " out of range"); + } // if + + int mantissa = (int) Math.floor(a_value); + int fraction = (int) Math.floor((a_value - mantissa) * 16384); + + int twoBitPart = mantissa; + if (mantissa < 0) { + twoBitPart = 4 + mantissa; + } // if + + retval = (twoBitPart << 14) | fraction; + + return retval; + } + + public static int toDeltaArg(int a_relativePpem, int a_step) { + int retval = 0; + + if (a_step < -8 || a_step > 8 || a_step == 0) { + throw new RuntimeException("Out of range"); + } // if + + int selector = 0; + if (a_step > 0) { + selector = a_step + 7; + } else { + selector = a_step + 8; + } // if + + retval = (a_relativePpem << 4) | (selector); + + return retval; + } + + // -------------------------------------------------------------- + + private ArrayList m_points = new ArrayList<>(); + private ArrayList m_endPtsOfContours = new ArrayList<>(); + private ArrayList m_instructions = new ArrayList<>(); + private ArrayList m_flags = new ArrayList<>(); + private ArrayList m_glyfIndeces = new ArrayList<>(); + private ArrayList m_arg1s = new ArrayList<>(); + private ArrayList m_arg2s = new ArrayList<>(); + + private boolean m_isSimple = true; + private int m_advanceWidth = 512; + + private int m_numOfCompositePoints = 0; + private int m_numOfCompositeContours = 0; + private int m_componentDepth = 0; + + private Point m_min = null; + private Point m_max = null; + + // -------------------------------------------------------------- + + public TTGlyph() { + init(); + } + + public void init() { + m_isSimple = true; + m_points.clear(); + m_endPtsOfContours.clear(); + m_instructions.clear(); + m_flags.clear(); + m_glyfIndeces.clear(); + m_arg1s.clear(); + m_arg2s.clear(); + m_advanceWidth = 512; + } + + public void buildCompound() { + init(); + + m_isSimple = false; + + addFlag(ARG_1_AND_2_ARE_WORDS + | ARGS_ARE_XY_VALUES + | ROUND_XY_TO_GRID + | MORE_COMPONENTS); + addFlag(ARG_1_AND_2_ARE_WORDS + | ARGS_ARE_XY_VALUES + | ROUND_XY_TO_GRID); + + addGlyfIndex(3); + addGlyfIndex(3); + + addArg1(0); + addArg2(0); + addArg1(0); + addArg2(500); + } + + /** + * add the index of the last point in the contour + * @param a_index + */ + public void addEndPoint(int a_value) { + m_endPtsOfContours.add(a_value); + } + + public int getNumOfContours() { + if (isSimple()) { + return m_endPtsOfContours.size(); + } else { + return -1; + } // if-else + } + + public int getEndPoint(int a_index) { + return m_endPtsOfContours.get(a_index); + } + + public int getAdvanceWidth() { + return m_advanceWidth; + } + + public void setAdvanceWidth(int a_value) { + m_advanceWidth = a_value; + } + + public Point getMax() { + if (m_max == null) { + m_max = new Point(0, 0); + } // if + + return m_max; + } + + public Point getMin() { + if (m_min == null) { + m_min = new Point(0, 0); + } // if + + return m_min; + } + + public boolean isSimple() { + return m_isSimple; + } + + public void setSimple(boolean a_isSimple) { + m_isSimple = a_isSimple; + } + + public void addInstruction(int a_value) { + m_instructions.add(a_value); + } + + public int getInstruction(int a_index) { + return m_instructions.get(a_index); + } + + public int getNumOfInstructions() { + return m_instructions.size(); + } + + public void addFlag(int a_value) { + m_flags.add(a_value); + } + + public int getFlag(int a_index) { + return m_flags.get(a_index); + } + + public int getNumOfFlags() { + return m_flags.size(); + } + + public void addPoint(Point a_value) { + m_points.add(a_value); + updateMinMax(a_value); + } + + private void updateMinMax(Point a_value) { + if (m_max == null) { + m_max = new Point(a_value); + } // if + + if (m_min == null) { + m_min = new Point(a_value); + } // if + + if (a_value.x > m_max.x) { + m_max.x = a_value.x; + } // if + + if (a_value.x < m_min.x) { + m_min.x = a_value.x; + } // if + + if (a_value.y > m_max.y) { + m_max.y = a_value.y; + } // if + + if (a_value.y < m_min.y) { + m_min.y = a_value.y; + } // if + } + + public Point getPoint(int a_index) { + return m_points.get(a_index); + } + + public int getNumOfPoints() { + return m_points.size(); + } + + public int getLastIndex() { + return m_points.size() - 1; + } + + public void addGlyfIndex(int a_value) { + m_glyfIndeces.add(a_value); + } + + public int getGlyfIndex(int a_index) { + return m_glyfIndeces.get(a_index); + } + + public void addArg1(int a_value) { + m_arg1s.add(a_value); + } + + public int getArg1(int a_index) { + return m_arg1s.get(a_index); + } + + public void addArg2(int a_value) { + m_arg2s.add(a_value); + } + + public int getArg2(int a_index) { + return m_arg2s.get(a_index); + } + + public int getNumOfCompositePoints() { + if (isSimple()) { + return getNumOfPoints(); + } else { + return m_numOfCompositePoints; + } + } + + public void setNumOfCompositePoints(int a_value) { + m_numOfCompositePoints = a_value; + } + + public int getNumOfCompositeContours() { + if (isSimple()) { + return getNumOfContours(); + } else { + return m_numOfCompositeContours; + } // if-else + } + + public void setNumOfCompositeContours(int a_value) { + m_numOfCompositeContours = a_value; + } + + public int getComponentDepth() { + if (isSimple()) { + return 0; + } else { + return m_componentDepth; + } // if-else + } + + public void setComponentDepth(int a_value) { + m_componentDepth = a_value; + } + + public int getLeftSideBearing() { + return getMin().x; + } + + public int getRightSideBearing() { + return getAdvanceWidth() - getMax().x; + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/TTName.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/TTName.java new file mode 100644 index 000000000..659712f16 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/TTName.java @@ -0,0 +1,93 @@ +/* + * $Id: TTName.java,v 1.2 2005/01/21 05:37:26 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2004, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa.truetype; + +public class TTName { + public static final int k_unicode = 0; + public static final int k_unicodeDefaultEncode = 0; + + public static final int k_macintosh = 1; + public static final int k_macRomanEncode = 0; + public static final int k_macEnglishLang = 0; + + public static final int k_microsoft = 3; + public static final int k_winSymbolEncode = 0; + public static final int k_winUnicodeEncode = 1; + public static final int k_winShiftJisEncode = 2; + public static final int k_winEnglishLang = 0x409; + private int m_platformId; + private int m_encodingId; + private int m_languageId; + private int m_nameId; + private byte m_bytes[]; + + public TTName(int a_platformId, + int a_encodingId, + int a_languageId, + int a_nameId, + byte a_bytes[]) { + m_platformId = a_platformId; + m_encodingId = a_encodingId; + m_languageId = a_languageId; + m_nameId = a_nameId; + m_bytes = a_bytes; + } + + public int getPlatformId() { + return m_platformId; + } + + public int getEncodingId() { + return m_encodingId; + } + + public int getLanguageId() { + return m_languageId; + } + + public int getNameId() { + return m_nameId; + } + + // BUGFIX 958996 + public byte[] getBytes() { + return m_bytes; + } + + public int getStringLength() { + return m_bytes.length; + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/TTPixelSize.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/TTPixelSize.java new file mode 100644 index 000000000..d81b15dc7 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/TTPixelSize.java @@ -0,0 +1,107 @@ +package org.doubletype.ossa.truetype; + +import java.util.ArrayList; + +public class TTPixelSize { + static private int s_em = 1024; + static private boolean s_isInitialized = false; + static private ArrayList s_list = new ArrayList<>(); + + static public int getEm() { + return s_em; + } + + static public ArrayList getList() { + initList(); + return s_list; + } + + static private void initList() { + if (s_isInitialized) + return; + + s_isInitialized = true; + + // s_list.add(new TTPixelSize(9, "9px: 7pt(96dpi)/9pt(72dpi)")); + // s_list.add(new TTPixelSize(10, "10px: 7.5pt(96dpi)/10pt(72dpi)")); + s_list.add(new TTPixelSize(11, "11px: 8pt(96dpi)/11pt(72dpi)")); + s_list.add(new TTPixelSize(12, "12px: 9pt(96dpi)/12pt(72dpi)")); + s_list.add(new TTPixelSize(13, "13px: 10pt(96dpi)/13pt(72dpi)")); + s_list.add(new TTPixelSize(14, "14px: 10.5pt(96dpi)/14pt(72dpi)")); + s_list.add(new TTPixelSize(15, "15px: 11pt(96dpi)/15pt(72dpi)")); + s_list.add(new TTPixelSize(16, "16px: 12pt(96dpi)/16pt(72dpi)")); + s_list.add(new TTPixelSize(17, "17px: 13pt(96dpi)/17pt(72dpi)")); + s_list.add(new TTPixelSize(18, "18px: 13.5pt(96dpi)/18pt(72dpi)")); + s_list.add(new TTPixelSize(19, "19px: 14pt(96dpi)/14pt(72dpi)")); + s_list.add(new TTPixelSize(20, "20px: 15pt(96dpi)/20pt(72dpi)")); + s_list.add(new TTPixelSize(21, "21px: 16pt(96dpi)/21pt(72dpi)")); + s_list.add(new TTPixelSize(22, "22px: 16.5pt(96dpi)/22pt(72dpi)")); + s_list.add(new TTPixelSize(23, "23px: 17pt(96dpi)/23pt(72dpi)")); + s_list.add(new TTPixelSize(24, "24px: 18pt(96dpi)/24pt(72dpi)")); + s_list.add(new TTPixelSize(27, "27px: 20pt(96dpi)")); + s_list.add(new TTPixelSize(29, "29px: 22pt(96dpi)")); + s_list.add(new TTPixelSize(32, "32px: 24pt(96dpi)")); + s_list.add(new TTPixelSize(33, "33px: 8pt(300dpi) ")); + // s_list.add(new TTPixelSize(35, "35px: 26pt(96dpi) ")); + s_list.add(new TTPixelSize(37, "37px: 28pt(96dpi)")); + // s_list.add(new TTPixelSize(38, "38px: 9pt(300dpi)"); + s_list.add(new TTPixelSize(42, "42px: 10pt(300dpi)")); + // s_list.add(new TTPixelSize(44, "44px: 10.5pt(300dpi)")); + s_list.add(new TTPixelSize(46, "46px: 11pt(300dpi)")); + s_list.add(new TTPixelSize(50, "50px: 12pt(300dpi)")); + s_list.add(new TTPixelSize(54, "54px: 13pt(300dpi)")); + s_list.add(new TTPixelSize(58, "58px: 14pt(300dpi)")); + s_list.add(new TTPixelSize(67, "67px: 16pt(300dpi)")); + s_list.add(new TTPixelSize(75, "75px: 18pt(300dpi)")); + s_list.add(new TTPixelSize(83, "83px: 20pt(300dpi)")); + s_list.add(new TTPixelSize(92, "92px: 22pt(300dpi)")); + s_list.add(new TTPixelSize(100, "100px: 24pt(300dpi)")); + } + + private int m_pixel; + private String m_description; + private int m_pixelWidths[]; + private int m_maxPixelWidth = 0; + + public TTPixelSize(int a_pixel, String a_description) + { + m_pixel = a_pixel; + m_description = a_description; + } + + public int getPixel() { + return m_pixel; + } + + public String getDescription() { + return m_description; + } + + /** + * sets the size of the pixel widths. Use num of glyphs. + * @param a_size + */ + public void setPixelWidthsSize(int a_size) { + m_pixelWidths = new int[a_size]; + m_maxPixelWidth = 0; + } + + public void setPixelWidth(int a_glyphIndex, int a_value) { + m_pixelWidths[a_glyphIndex] = a_value; + if (a_value > m_maxPixelWidth) { + m_maxPixelWidth = a_value; + } // if + } + + public int [] getPixelWidths() { + return m_pixelWidths; + } + + public int getPixelWidth(int a_glyphIndex) { + return m_pixelWidths[a_glyphIndex]; + } + + public int getMaxPixelWidth() { + return m_maxPixelWidth; + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/TTUnicodeRange.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/TTUnicodeRange.java new file mode 100644 index 000000000..c55084c16 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/truetype/TTUnicodeRange.java @@ -0,0 +1,380 @@ +/* + * $Id: TTUnicodeRange.java,v 1.1 2004/01/25 11:00:10 eed3si9n Exp $ + * + * $Copyright: copyright (c) 2003-2004, e.e d3si9n $ + * $License: + * This source code is part of DoubleType. + * DoubleType is a graphical typeface designer. + * + * 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 + * + * In addition, as a special exception, e.e d3si9n gives permission to + * link the code of this program with any Java Platform that is available + * to public with free of charge, including but not limited to + * Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE), + * and distribute linked combinations including the two. + * You must obey the GNU General Public License in all respects for all + * of the code used other than Java Platform. If you modify this file, + * you may extend this exception to your version of the file, but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. + * $ + */ + +package org.doubletype.ossa.truetype; + +import java.util.*; + +import java.lang.Character.UnicodeBlock; + +/** + * @author e.e + */ +public class TTUnicodeRange implements Comparable { + public static final long k_notDef = 0x0001; + public static final long k_null = 0x0000; + public static final long k_cr = 0x000D; + public static final long k_space = 0x0020; + + static private boolean s_isInitialized = false; + static private ArrayList s_list = new ArrayList<>(); + static private TTUnicodeRange s_selected = null; + + static public TTUnicodeRange of(long a_unicode) { + initList(); + + TTUnicodeRange retval = null; + UnicodeBlock block = UnicodeBlock.of((int)a_unicode); + if (block == null) + return retval; + + int i; + for (i = 0; i < s_list.size(); i++) { + TTUnicodeRange range = s_list.get(i); + if (range.m_block.equals(block)) { + return range; + } // if + } // for i + + return retval; + } + + static public TTUnicodeRange getLastFound() { + return s_selected; + } + + static private void initList() { + if (s_isInitialized) + return; + + s_isInitialized = true; + + s_list.add(new TTUnicodeRange( + UnicodeBlock.BASIC_LATIN, 0x0020, 0x007F, 0, 63)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.LATIN_1_SUPPLEMENT, 0x0080, 0x00FF, 1, 0)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.LATIN_EXTENDED_A, 0x0100, 0x017f, 2)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.LATIN_EXTENDED_B, 0x0180, 0x024f, 3)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.IPA_EXTENSIONS, 0x0250, 0x02af, 4)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.SPACING_MODIFIER_LETTERS, 0x02B0, 0x02FF, 5)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.COMBINING_DIACRITICAL_MARKS, 0x0300, 0x036F, 6)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.GREEK, 0x0370, 0x03FF, 7, 3)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.CYRILLIC, 0x0400, 0x04FF, 9, 2)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.ARMENIAN, 0x0530, 0x058F, 10)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.HEBREW, 0x0590, 0x05FF, 11, 5)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.ARABIC, 0x0600, 0x06FF, 13, 6)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.SYRIAC, 0x0700, 0x074F, 71)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.THAANA, 0x0780, 0x07BF, 72)); + + s_list.add(new TTUnicodeRange( + UnicodeBlock.DEVANAGARI, 0x0900, 0x097F, 15)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.BENGALI, 0x0980, 0x09FF, 16)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.GURMUKHI, 0x0A00, 0x0A7F, 17)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.GUJARATI, 0x0A80, 0x0AFF, 18)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.ORIYA, 0x0B00, 0x0B7F, 19)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.TAMIL, 0x0B80, 0x0BFF, 20)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.TELUGU, 0x0C00, 0x0C7F, 21)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.KANNADA, 0x0C80, 0x0CFF, 22)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.MALAYALAM, 0x0D00, 0x0D7F, 23)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.SINHALA, 0x0D80, 0x0DFF, 73)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.THAI, 0x0E00, 0x0E7F, 24, 16)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.LAO, 0x0E80, 0x0EFF, 25)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.TIBETAN, 0x0F00, 0x0FFF, 70)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.MYANMAR, 0x1000, 0x109F, 74)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.GEORGIAN, 0x10A0, 0x10FF, 26)); + // TODO: wansung or johab? + s_list.add(new TTUnicodeRange( + UnicodeBlock.HANGUL_JAMO, 0x1100, 0x11FF, 28, 19)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.ETHIOPIC, 0x1200, 0x137F, 75)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.CHEROKEE, 0x13A0, 0x13FF, 76)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS, 0x1400, 0x167F, 77)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.OGHAM, 0x1680, 0x169F, 78)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.RUNIC, 0x16A0, 0x16FF, 79)); + + // TODO: tagalog, hanunoo, buhid, tagbanwa + + s_list.add(new TTUnicodeRange( + UnicodeBlock.KHMER, 0x1780, 0x17FF, 80)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.MONGOLIAN, 0x1800, 0x18AF, 81)); + + // linbu, tai le, khmer symbol, phonetic extensions, + + s_list.add(new TTUnicodeRange( + UnicodeBlock.LATIN_EXTENDED_ADDITIONAL, 0x1E00, 0x1EFF, 29)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.GREEK_EXTENDED, 0x1F00, 0x1FFF, 30)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.GENERAL_PUNCTUATION, 0x2000, 0x206F, 31)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.SUPERSCRIPTS_AND_SUBSCRIPTS, 0x2070, 0x209F, 32)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.CURRENCY_SYMBOLS, 0x20A0, 0x20CF, 33)); + + // combining diacritical marks + s_list.add(new TTUnicodeRange( + UnicodeBlock.COMBINING_MARKS_FOR_SYMBOLS, 0x20D0, 0x20FF, 34)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.LETTERLIKE_SYMBOLS, 0x2100, 0x214F, 35)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.NUMBER_FORMS, 0x2150, 0x218F, 36)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.ARROWS, 0x2190, 0x21FF, 37)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.MATHEMATICAL_OPERATORS, 0x2200, 0x22FF, 38)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.MISCELLANEOUS_TECHNICAL, 0x2300, 0x23FF, 39)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.CONTROL_PICTURES, 0x2400, 0x243F, 40)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.OPTICAL_CHARACTER_RECOGNITION, 0x2440, 0x245F, 41)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.ENCLOSED_ALPHANUMERICS, 0x2460, 0x24FF, 42)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.BOX_DRAWING, 0x2500, 0x257F, 43)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.BLOCK_ELEMENTS, 0x2580, 0x259F, 44)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.GEOMETRIC_SHAPES, 0x25A0, 0x25FF, 45)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.MISCELLANEOUS_SYMBOLS, 0x2600, 0x26FF, 46)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.DINGBATS, 0x2700, 0x27BF, 47)); + + // TODO: mics. math symbols A, supplemental arrows A + + s_list.add(new TTUnicodeRange( + UnicodeBlock.BRAILLE_PATTERNS, 0x2800, 0x28FF, 82)); + + // TODO: supplemental arrows B, mics. math symbols B, + // supplemental math op., mics. symbols and arrows + + +// CJKV supplements + s_list.add(new TTUnicodeRange( + UnicodeBlock.CJK_RADICALS_SUPPLEMENT, 0x2E80, 0x2EFF, 59)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.KANGXI_RADICALS, 0x2F00, 0x2FDF, 59)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.IDEOGRAPHIC_DESCRIPTION_CHARACTERS, 0x2FF0, 0x2FFF, 59)); + + + s_list.add(new TTUnicodeRange( + UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION, 0x3000, 0x303f, 48)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.HIRAGANA, 0x3040, 0x309f, 49, 17)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.KATAKANA, 0x30a0, 0x30ff, 50, 17)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.BOPOMOFO, 0x3100, 0x312f, 51)); + // TODO: wansung or johab? + s_list.add(new TTUnicodeRange( + UnicodeBlock.HANGUL_COMPATIBILITY_JAMO, 0x3130, 0x0318F, 52, 19)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.KANBUN, 0x3190, 0x319F, 59)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.BOPOMOFO_EXTENDED, 0x31A0, 0x31BF, 51)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.KATAKANA_PHONETIC_EXTENSIONS, 0x31F0, 0x31FF, 50, 17)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.ENCLOSED_CJK_LETTERS_AND_MONTHS, 0x3200, 0x32FF, 54)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.CJK_COMPATIBILITY, 0x3300, 0x33ff, 55)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A, 0x03400, 0x4dbf, 59)); + // TODO: yijing hex symbols + + // the kanji characters + s_list.add(new TTUnicodeRange( + UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS, 0x4e00, 0x9fff, 59, 17)); + + s_list.add(new TTUnicodeRange( + UnicodeBlock.YI_SYLLABLES, 0xA000, 0xA48F, 83)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.YI_RADICALS, 0xA490, 0xA4CF, 83)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.HANGUL_SYLLABLES, 0xAC00, 0xD7AF, 56)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.HIGH_SURROGATES, 0xD800, 0xDB7F, 0)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.HIGH_PRIVATE_USE_SURROGATES, 0xDB80, 0xDBFF, 0)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.LOW_SURROGATES, 0xDC00, 0xDFFF, 0)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.PRIVATE_USE_AREA, 0xE000, 0xF8FF, 60)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS, 0xf900, 0xfaff, 61)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.ALPHABETIC_PRESENTATION_FORMS, 0xFB00, 0xFB4F, 62)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.ARABIC_PRESENTATION_FORMS_A, 0xFB50, 0xFDFF, 62)); + + // TODO: variation selectors + + s_list.add(new TTUnicodeRange( + UnicodeBlock.COMBINING_HALF_MARKS, 0xFE20, 0xFE2F, 64)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.CJK_COMPATIBILITY_FORMS, 0xFE30, 0xFE4F, 65)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.SMALL_FORM_VARIANTS, 0xFE50, 0xFE6F, 66)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.ARABIC_PRESENTATION_FORMS_B, 0xFE70, 0xFEFF, 67)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS, 0xFF00, 0xFFEF, 68, 17)); + s_list.add(new TTUnicodeRange( + UnicodeBlock.SPECIALS, 0xFFF0, 0xFFFF, 69)); + } + + static public boolean find(String a_unicodeRange) { + initList(); + + s_selected = null; + + int i; + for (i = 0; i < s_list.size(); i++) { + TTUnicodeRange range = (TTUnicodeRange) s_list.get(i); + if (range.m_block.toString().equals(a_unicodeRange)) { + s_selected = range; + + return true; + } // if + } // for i + + return false; + } + + + private UnicodeBlock m_block = null; + private long m_start = 0; + private long m_end = 0; + + /** http://www.microsoft.com/typography/otspec/os2.htm + */ + private int m_osTwoFlag = 0; + + /** http://www.microsoft.com/typography/otspec/os2.htm + */ + private int m_codePageFlag = 0; + + public TTUnicodeRange(UnicodeBlock a_block, + long a_start, + long a_end, + int a_osTwoFlag) + { + m_block = a_block; + m_start = a_start; + m_end = a_end; + m_osTwoFlag = a_osTwoFlag; + } + + public TTUnicodeRange(UnicodeBlock a_block, + long a_start, + long a_end, + int a_osTwoFlag, + int a_codePageFlag) + { + m_block = a_block; + m_start = a_start; + m_end = a_end; + m_osTwoFlag = a_osTwoFlag; + m_codePageFlag = a_codePageFlag; + } + + public boolean equals(Object a_object) { + TTUnicodeRange object = (TTUnicodeRange) a_object; + return (m_start == object.m_start); + } + + public int compareTo(Object a_object) { + TTUnicodeRange object = (TTUnicodeRange) a_object; + if (this.m_start < object.m_start) { + return -1; + } else if (this.m_start == object.m_start) { + return 0; + } else + return 1; + } + + public String toString() { + return m_block.toString(); + } + + public long getStartCode() { + return m_start; + } + + public long getEndCode() { + return m_end; + } + + public int getOsTwoFlag() { + return m_osTwoFlag; + } + + public int getCodeRangeFlag() { + return m_codePageFlag; + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/xml/AbstractGlyphFactory.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/xml/AbstractGlyphFactory.java new file mode 100644 index 000000000..d2d75cb43 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/xml/AbstractGlyphFactory.java @@ -0,0 +1,3291 @@ +/* + * The Relaxer artifact + * Copyright (c) 2000-2004, ASAMI Tomoharu, All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package org.doubletype.ossa.xml; + +import java.io.*; +import java.net.URL; +import javax.xml.parsers.*; +import org.w3c.dom.*; +import org.xml.sax.*; + +/** + * AbstractGlyphFactory is generated by Relaxer based on glyph.rng. + * + * @version glyph.rng 1.0 (Tue Nov 09 20:22:48 EST 2004) + * @author Relaxer 1.1b (http://www.relaxer.org) + */ +public abstract class AbstractGlyphFactory implements IGlyphFactory { + protected org.xml.sax.ErrorHandler errorHandler; + protected org.xml.sax.EntityResolver entityResolver; + protected String baseUri; + + /** + * Gets a Class of XParamListParam. + * + * @return Class + */ + public Class getXParamListParamClass() { + return (createXParamListParam().getClass()); + } + + /** + * Gets a Class of XHeadGlobal. + * + * @return Class + */ + public Class getXHeadGlobalClass() { + return (createXHeadGlobal().getClass()); + } + + /** + * Gets a Class of XHeadLocal. + * + * @return Class + */ + public Class getXHeadLocalClass() { + return (createXHeadLocal().getClass()); + } + + /** + * Gets a Class of XHead. + * + * @return Class + */ + public Class getXHeadClass() { + return (createXHead().getClass()); + } + + /** + * Gets a Class of XGlyphFile. + * + * @return Class + */ + public Class getXGlyphFileClass() { + return (createXGlyphFile().getClass()); + } + + /** + * Gets a Class of XContour. + * + * @return Class + */ + public Class getXContourClass() { + return (createXContour().getClass()); + } + + /** + * Gets a Class of XPoint2d. + * + * @return Class + */ + public Class getXPoint2dClass() { + return (createXPoint2d().getClass()); + } + + /** + * Gets a Class of XInvokePos. + * + * @return Class + */ + public Class getXInvokePosClass() { + return (createXInvokePos().getClass()); + } + + /** + * Gets a Class of XInvokeArg. + * + * @return Class + */ + public Class getXInvokeArgClass() { + return (createXInvokeArg().getClass()); + } + + /** + * Gets a Class of XInvokeVarg. + * + * @return Class + */ + public Class getXInvokeVargClass() { + return (createXInvokeVarg().getClass()); + } + + /** + * Gets a Class of XInvoke. + * + * @return Class + */ + public Class getXInvokeClass() { + return (createXInvoke().getClass()); + } + + /** + * Gets a Class of XInclude. + * + * @return Class + */ + public Class getXIncludeClass() { + return (createXInclude().getClass()); + } + + /** + * Gets a Class of XModule. + * + * @return Class + */ + public Class getXModuleClass() { + return (createXModule().getClass()); + } + + /** + * Gets a Class of XBody. + * + * @return Class + */ + public Class getXBodyClass() { + return (createXBody().getClass()); + } + + /** + * Gets a Class of XStartGlyphElement. + * + * @return Class + */ + public Class getXStartGlyphElementClass() { + return (createXStartGlyphElement().getClass()); + } + + /** + * Gets a Class of XControlPoint. + * + * @return Class + */ + public Class getXControlPointClass() { + return (createXControlPoint().getClass()); + } + + /** + * Gets a Class of XHint. + * + * @return Class + */ + public Class getXHintClass() { + return (createXHint().getClass()); + } + + /** + * Gets a Class of XContourPoint. + * + * @return Class + */ + public Class getXContourPointClass() { + return (createXContourPoint().getClass()); + } + + /** + * Gets a Class of XParamList. + * + * @return Class + */ + public Class getXParamListClass() { + return (createXParamList().getClass()); + } + + /** + * Sets a errorHandler. + * + * @param errorHandler + */ + public void setErrorHandler(org.xml.sax.ErrorHandler errorHandler) { + this.errorHandler = errorHandler; + } + + /** + * Gets a errorHandler. + * + * @return org.xml.sax.ErrorHandler + */ + public org.xml.sax.ErrorHandler getErrorHandler() { + return (errorHandler); + } + + /** + * Sets a entityResolver. + * + * @param entityResolver + */ + public void setEntityResolver(org.xml.sax.EntityResolver entityResolver) { + this.entityResolver = entityResolver; + } + + /** + * Gets a entityResolver. + * + * @return org.xml.sax.EntityResolver + */ + public org.xml.sax.EntityResolver getEntityResolver() { + return (entityResolver); + } + + /** + * Sets a baseUri. + * + * @param baseUri + */ + public void setBaseUri(String baseUri) { + this.baseUri = baseUri; + } + + /** + * Gets a baseUri. + * + * @return String + */ + public String getBaseUri() { + return (baseUri); + } + + /** + * Creates a Object by the File file. + * This method is a template method for concrete classes. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return Object + */ + public Object create(File file) throws IOException, SAXException, ParserConfigurationException { + Object node = create(UJAXP.getDocument(file, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (node); + } + + /** + * Creates a Object by the String representation of URI uri. + * This method is a template method for concrete classes. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return Object + */ + public Object create(String uri) throws IOException, SAXException, ParserConfigurationException { + Object node = create(UJAXP.getDocument(uri, baseUri, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (node); + } + + /** + * Creates a Object by the URL url. + * This method is a template method for concrete classes. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return Object + */ + public Object create(URL url) throws IOException, SAXException, ParserConfigurationException { + Object node = create(UJAXP.getDocument(url, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (node); + } + + /** + * Creates a Object by the InputStream in. + * This method is a template method for concrete classes. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return Object + */ + public Object create(InputStream in) throws IOException, SAXException, ParserConfigurationException { + Object node = create(UJAXP.getDocument(in, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (node); + } + + /** + * Creates a Object by the InputSource is. + * This method is a template method for concrete classes. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return Object + */ + public Object create(InputSource is) throws IOException, SAXException, ParserConfigurationException { + Object node = create(UJAXP.getDocument(is, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (node); + } + + /** + * Creates a Object by the Reader reader. + * This method is a template method for concrete classes. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return Object + */ + public Object create(Reader reader) throws IOException, SAXException, ParserConfigurationException { + Object node = create(UJAXP.getDocument(reader, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (node); + } + + /** + * Creates a Object by the copy Object. + * This method is a template method for concrete classes. + * + * @param source + * @return Object + */ + public Object create(Object source) { + if (source instanceof XParamListParam) { + XParamListParam node = createXParamListParam(); + node.setup((XParamListParam)source); + return(node); + } else if (source instanceof XHeadGlobal) { + XHeadGlobal node = createXHeadGlobal(); + node.setup((XHeadGlobal)source); + return(node); + } else if (source instanceof XHeadLocal) { + XHeadLocal node = createXHeadLocal(); + node.setup((XHeadLocal)source); + return(node); + } else if (source instanceof XHead) { + XHead node = createXHead(); + node.setup((XHead)source); + return(node); + } else if (source instanceof XGlyphFile) { + XGlyphFile node = createXGlyphFile(); + node.setup((XGlyphFile)source); + return(node); + } else if (source instanceof XContour) { + XContour node = createXContour(); + node.setup((XContour)source); + return(node); + } else if (source instanceof XPoint2d) { + XPoint2d node = createXPoint2d(); + node.setup((XPoint2d)source); + return(node); + } else if (source instanceof XInvokePos) { + XInvokePos node = createXInvokePos(); + node.setup((XInvokePos)source); + return(node); + } else if (source instanceof XInvokeArg) { + XInvokeArg node = createXInvokeArg(); + node.setup((XInvokeArg)source); + return(node); + } else if (source instanceof XInvokeVarg) { + XInvokeVarg node = createXInvokeVarg(); + node.setup((XInvokeVarg)source); + return(node); + } else if (source instanceof XInvoke) { + XInvoke node = createXInvoke(); + node.setup((XInvoke)source); + return(node); + } else if (source instanceof XInclude) { + XInclude node = createXInclude(); + node.setup((XInclude)source); + return(node); + } else if (source instanceof XModule) { + XModule node = createXModule(); + node.setup((XModule)source); + return(node); + } else if (source instanceof XBody) { + XBody node = createXBody(); + node.setup((XBody)source); + return(node); + } else if (source instanceof XStartGlyphElement) { + XStartGlyphElement node = createXStartGlyphElement(); + node.setup((XStartGlyphElement)source); + return(node); + } else if (source instanceof XControlPoint) { + XControlPoint node = createXControlPoint(); + node.setup((XControlPoint)source); + return(node); + } else if (source instanceof XHint) { + XHint node = createXHint(); + node.setup((XHint)source); + return(node); + } else if (source instanceof XContourPoint) { + XContourPoint node = createXContourPoint(); + node.setup((XContourPoint)source); + return(node); + } else { + return (null); + } + } + + /** + * Creates a Object by the Document doc. + * This method is a template method for concrete classes. + * + * @param doc + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return Object + */ + public Object create(Document doc) throws IOException, SAXException, ParserConfigurationException { + Object node = create(doc.getDocumentElement()); + return (node); + } + + /** + * Creates a Object by the Element element. + * This method is a template method for concrete classes. + * + * @param element + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return Object + */ + public Object create(Element element) throws IOException, SAXException, ParserConfigurationException { + if (XParamListParam.isMatch(element)) { + XParamListParam node = createXParamListParam(); + node.setup(element); + return(node); + } else if (XHeadGlobal.isMatch(element)) { + XHeadGlobal node = createXHeadGlobal(); + node.setup(element); + return(node); + } else if (XHeadLocal.isMatch(element)) { + XHeadLocal node = createXHeadLocal(); + node.setup(element); + return(node); + } else if (XHead.isMatch(element)) { + XHead node = createXHead(); + node.setup(element); + return(node); + } else if (XGlyphFile.isMatch(element)) { + XGlyphFile node = createXGlyphFile(); + node.setup(element); + return(node); + } else if (XContour.isMatch(element)) { + XContour node = createXContour(); + node.setup(element); + return(node); + } else if (XPoint2d.isMatch(element)) { + XPoint2d node = createXPoint2d(); + node.setup(element); + return(node); + } else if (XInvokePos.isMatch(element)) { + XInvokePos node = createXInvokePos(); + node.setup(element); + return(node); + } else if (XInvokeArg.isMatch(element)) { + XInvokeArg node = createXInvokeArg(); + node.setup(element); + return(node); + } else if (XInvokeVarg.isMatch(element)) { + XInvokeVarg node = createXInvokeVarg(); + node.setup(element); + return(node); + } else if (XInvoke.isMatch(element)) { + XInvoke node = createXInvoke(); + node.setup(element); + return(node); + } else if (XInclude.isMatch(element)) { + XInclude node = createXInclude(); + node.setup(element); + return(node); + } else if (XModule.isMatch(element)) { + XModule node = createXModule(); + node.setup(element); + return(node); + } else if (XBody.isMatch(element)) { + XBody node = createXBody(); + node.setup(element); + return(node); + } else if (XStartGlyphElement.isMatch(element)) { + XStartGlyphElement node = createXStartGlyphElement(); + node.setup(element); + return(node); + } else if (XControlPoint.isMatch(element)) { + XControlPoint node = createXControlPoint(); + node.setup(element); + return(node); + } else if (XHint.isMatch(element)) { + XHint node = createXHint(); + node.setup(element); + return(node); + } else if (XContourPoint.isMatch(element)) { + XContourPoint node = createXContourPoint(); + node.setup(element); + return(node); + } else { + return (null); + } + } + + /** + * Creates a XParamListParam by the File file. + * This method is a template method for concrete classes. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XParamListParam + */ + public XParamListParam createXParamListParam(File file) throws IOException, SAXException, ParserConfigurationException { + XParamListParam xParamListParam_ = createXParamListParam(); + xParamListParam_.setup(UJAXP.getDocument(file, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xParamListParam_); + } + + /** + * Creates a XHeadGlobal by the File file. + * This method is a template method for concrete classes. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHeadGlobal + */ + public XHeadGlobal createXHeadGlobal(File file) throws IOException, SAXException, ParserConfigurationException { + XHeadGlobal xHeadGlobal_ = createXHeadGlobal(); + xHeadGlobal_.setup(UJAXP.getDocument(file, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xHeadGlobal_); + } + + /** + * Creates a XHeadLocal by the File file. + * This method is a template method for concrete classes. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHeadLocal + */ + public XHeadLocal createXHeadLocal(File file) throws IOException, SAXException, ParserConfigurationException { + XHeadLocal xHeadLocal_ = createXHeadLocal(); + xHeadLocal_.setup(UJAXP.getDocument(file, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xHeadLocal_); + } + + /** + * Creates a XHead by the File file. + * This method is a template method for concrete classes. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHead + */ + public XHead createXHead(File file) throws IOException, SAXException, ParserConfigurationException { + XHead xHead_ = createXHead(); + xHead_.setup(UJAXP.getDocument(file, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xHead_); + } + + /** + * Creates a XGlyphFile by the File file. + * This method is a template method for concrete classes. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XGlyphFile + */ + public XGlyphFile createXGlyphFile(File file) throws IOException, SAXException, ParserConfigurationException { + XGlyphFile xGlyphFile_ = createXGlyphFile(); + xGlyphFile_.setup(UJAXP.getDocument(file, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xGlyphFile_); + } + + /** + * Creates a XContour by the File file. + * This method is a template method for concrete classes. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XContour + */ + public XContour createXContour(File file) throws IOException, SAXException, ParserConfigurationException { + XContour xContour_ = createXContour(); + xContour_.setup(UJAXP.getDocument(file, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xContour_); + } + + /** + * Creates a XPoint2d by the File file. + * This method is a template method for concrete classes. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XPoint2d + */ + public XPoint2d createXPoint2d(File file) throws IOException, SAXException, ParserConfigurationException { + XPoint2d xPoint2d_ = createXPoint2d(); + xPoint2d_.setup(UJAXP.getDocument(file, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xPoint2d_); + } + + /** + * Creates a XInvokePos by the File file. + * This method is a template method for concrete classes. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokePos + */ + public XInvokePos createXInvokePos(File file) throws IOException, SAXException, ParserConfigurationException { + XInvokePos xInvokePos_ = createXInvokePos(); + xInvokePos_.setup(UJAXP.getDocument(file, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xInvokePos_); + } + + /** + * Creates a XInvokeArg by the File file. + * This method is a template method for concrete classes. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokeArg + */ + public XInvokeArg createXInvokeArg(File file) throws IOException, SAXException, ParserConfigurationException { + XInvokeArg xInvokeArg_ = createXInvokeArg(); + xInvokeArg_.setup(UJAXP.getDocument(file, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xInvokeArg_); + } + + /** + * Creates a XInvokeVarg by the File file. + * This method is a template method for concrete classes. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokeVarg + */ + public XInvokeVarg createXInvokeVarg(File file) throws IOException, SAXException, ParserConfigurationException { + XInvokeVarg xInvokeVarg_ = createXInvokeVarg(); + xInvokeVarg_.setup(UJAXP.getDocument(file, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xInvokeVarg_); + } + + /** + * Creates a XInvoke by the File file. + * This method is a template method for concrete classes. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvoke + */ + public XInvoke createXInvoke(File file) throws IOException, SAXException, ParserConfigurationException { + XInvoke xInvoke_ = createXInvoke(); + xInvoke_.setup(UJAXP.getDocument(file, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xInvoke_); + } + + /** + * Creates a XInclude by the File file. + * This method is a template method for concrete classes. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInclude + */ + public XInclude createXInclude(File file) throws IOException, SAXException, ParserConfigurationException { + XInclude xInclude_ = createXInclude(); + xInclude_.setup(UJAXP.getDocument(file, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xInclude_); + } + + /** + * Creates a XModule by the File file. + * This method is a template method for concrete classes. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XModule + */ + public XModule createXModule(File file) throws IOException, SAXException, ParserConfigurationException { + XModule xModule_ = createXModule(); + xModule_.setup(UJAXP.getDocument(file, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xModule_); + } + + /** + * Creates a XBody by the File file. + * This method is a template method for concrete classes. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XBody + */ + public XBody createXBody(File file) throws IOException, SAXException, ParserConfigurationException { + XBody xBody_ = createXBody(); + xBody_.setup(UJAXP.getDocument(file, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xBody_); + } + + /** + * Creates a XStartGlyphElement by the File file. + * This method is a template method for concrete classes. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XStartGlyphElement + */ + public XStartGlyphElement createXStartGlyphElement(File file) throws IOException, SAXException, ParserConfigurationException { + XStartGlyphElement xStartGlyphElement_ = createXStartGlyphElement(); + xStartGlyphElement_.setup(UJAXP.getDocument(file, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xStartGlyphElement_); + } + + /** + * Creates a XControlPoint by the File file. + * This method is a template method for concrete classes. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XControlPoint + */ + public XControlPoint createXControlPoint(File file) throws IOException, SAXException, ParserConfigurationException { + XControlPoint xControlPoint_ = createXControlPoint(); + xControlPoint_.setup(UJAXP.getDocument(file, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xControlPoint_); + } + + /** + * Creates a XHint by the File file. + * This method is a template method for concrete classes. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHint + */ + public XHint createXHint(File file) throws IOException, SAXException, ParserConfigurationException { + XHint xHint_ = createXHint(); + xHint_.setup(UJAXP.getDocument(file, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xHint_); + } + + /** + * Creates a XContourPoint by the File file. + * This method is a template method for concrete classes. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XContourPoint + */ + public XContourPoint createXContourPoint(File file) throws IOException, SAXException, ParserConfigurationException { + XContourPoint xContourPoint_ = createXContourPoint(); + xContourPoint_.setup(UJAXP.getDocument(file, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xContourPoint_); + } + + /** + * Creates a XParamListParam + * by the String representation of URI uri. + * This method is a template method for concrete classes. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XParamListParam + */ + public XParamListParam createXParamListParam(String uri) throws IOException, SAXException, ParserConfigurationException { + XParamListParam xParamListParam_ = createXParamListParam(); + xParamListParam_.setup(UJAXP.getDocument(uri, baseUri, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xParamListParam_); + } + + /** + * Creates a XHeadGlobal + * by the String representation of URI uri. + * This method is a template method for concrete classes. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHeadGlobal + */ + public XHeadGlobal createXHeadGlobal(String uri) throws IOException, SAXException, ParserConfigurationException { + XHeadGlobal xHeadGlobal_ = createXHeadGlobal(); + xHeadGlobal_.setup(UJAXP.getDocument(uri, baseUri, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xHeadGlobal_); + } + + /** + * Creates a XHeadLocal + * by the String representation of URI uri. + * This method is a template method for concrete classes. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHeadLocal + */ + public XHeadLocal createXHeadLocal(String uri) throws IOException, SAXException, ParserConfigurationException { + XHeadLocal xHeadLocal_ = createXHeadLocal(); + xHeadLocal_.setup(UJAXP.getDocument(uri, baseUri, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xHeadLocal_); + } + + /** + * Creates a XHead + * by the String representation of URI uri. + * This method is a template method for concrete classes. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHead + */ + public XHead createXHead(String uri) throws IOException, SAXException, ParserConfigurationException { + XHead xHead_ = createXHead(); + xHead_.setup(UJAXP.getDocument(uri, baseUri, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xHead_); + } + + /** + * Creates a XGlyphFile + * by the String representation of URI uri. + * This method is a template method for concrete classes. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XGlyphFile + */ + public XGlyphFile createXGlyphFile(String uri) throws IOException, SAXException, ParserConfigurationException { + XGlyphFile xGlyphFile_ = createXGlyphFile(); + xGlyphFile_.setup(UJAXP.getDocument(uri, baseUri, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xGlyphFile_); + } + + /** + * Creates a XContour + * by the String representation of URI uri. + * This method is a template method for concrete classes. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XContour + */ + public XContour createXContour(String uri) throws IOException, SAXException, ParserConfigurationException { + XContour xContour_ = createXContour(); + xContour_.setup(UJAXP.getDocument(uri, baseUri, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xContour_); + } + + /** + * Creates a XPoint2d + * by the String representation of URI uri. + * This method is a template method for concrete classes. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XPoint2d + */ + public XPoint2d createXPoint2d(String uri) throws IOException, SAXException, ParserConfigurationException { + XPoint2d xPoint2d_ = createXPoint2d(); + xPoint2d_.setup(UJAXP.getDocument(uri, baseUri, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xPoint2d_); + } + + /** + * Creates a XInvokePos + * by the String representation of URI uri. + * This method is a template method for concrete classes. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokePos + */ + public XInvokePos createXInvokePos(String uri) throws IOException, SAXException, ParserConfigurationException { + XInvokePos xInvokePos_ = createXInvokePos(); + xInvokePos_.setup(UJAXP.getDocument(uri, baseUri, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xInvokePos_); + } + + /** + * Creates a XInvokeArg + * by the String representation of URI uri. + * This method is a template method for concrete classes. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokeArg + */ + public XInvokeArg createXInvokeArg(String uri) throws IOException, SAXException, ParserConfigurationException { + XInvokeArg xInvokeArg_ = createXInvokeArg(); + xInvokeArg_.setup(UJAXP.getDocument(uri, baseUri, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xInvokeArg_); + } + + /** + * Creates a XInvokeVarg + * by the String representation of URI uri. + * This method is a template method for concrete classes. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokeVarg + */ + public XInvokeVarg createXInvokeVarg(String uri) throws IOException, SAXException, ParserConfigurationException { + XInvokeVarg xInvokeVarg_ = createXInvokeVarg(); + xInvokeVarg_.setup(UJAXP.getDocument(uri, baseUri, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xInvokeVarg_); + } + + /** + * Creates a XInvoke + * by the String representation of URI uri. + * This method is a template method for concrete classes. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvoke + */ + public XInvoke createXInvoke(String uri) throws IOException, SAXException, ParserConfigurationException { + XInvoke xInvoke_ = createXInvoke(); + xInvoke_.setup(UJAXP.getDocument(uri, baseUri, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xInvoke_); + } + + /** + * Creates a XInclude + * by the String representation of URI uri. + * This method is a template method for concrete classes. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInclude + */ + public XInclude createXInclude(String uri) throws IOException, SAXException, ParserConfigurationException { + XInclude xInclude_ = createXInclude(); + xInclude_.setup(UJAXP.getDocument(uri, baseUri, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xInclude_); + } + + /** + * Creates a XModule + * by the String representation of URI uri. + * This method is a template method for concrete classes. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XModule + */ + public XModule createXModule(String uri) throws IOException, SAXException, ParserConfigurationException { + XModule xModule_ = createXModule(); + xModule_.setup(UJAXP.getDocument(uri, baseUri, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xModule_); + } + + /** + * Creates a XBody + * by the String representation of URI uri. + * This method is a template method for concrete classes. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XBody + */ + public XBody createXBody(String uri) throws IOException, SAXException, ParserConfigurationException { + XBody xBody_ = createXBody(); + xBody_.setup(UJAXP.getDocument(uri, baseUri, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xBody_); + } + + /** + * Creates a XStartGlyphElement + * by the String representation of URI uri. + * This method is a template method for concrete classes. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XStartGlyphElement + */ + public XStartGlyphElement createXStartGlyphElement(String uri) throws IOException, SAXException, ParserConfigurationException { + XStartGlyphElement xStartGlyphElement_ = createXStartGlyphElement(); + xStartGlyphElement_.setup(UJAXP.getDocument(uri, baseUri, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xStartGlyphElement_); + } + + /** + * Creates a XControlPoint + * by the String representation of URI uri. + * This method is a template method for concrete classes. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XControlPoint + */ + public XControlPoint createXControlPoint(String uri) throws IOException, SAXException, ParserConfigurationException { + XControlPoint xControlPoint_ = createXControlPoint(); + xControlPoint_.setup(UJAXP.getDocument(uri, baseUri, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xControlPoint_); + } + + /** + * Creates a XHint + * by the String representation of URI uri. + * This method is a template method for concrete classes. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHint + */ + public XHint createXHint(String uri) throws IOException, SAXException, ParserConfigurationException { + XHint xHint_ = createXHint(); + xHint_.setup(UJAXP.getDocument(uri, baseUri, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xHint_); + } + + /** + * Creates a XContourPoint + * by the String representation of URI uri. + * This method is a template method for concrete classes. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XContourPoint + */ + public XContourPoint createXContourPoint(String uri) throws IOException, SAXException, ParserConfigurationException { + XContourPoint xContourPoint_ = createXContourPoint(); + xContourPoint_.setup(UJAXP.getDocument(uri, baseUri, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xContourPoint_); + } + + /** + * Creates a XParamListParam by the URL url. + * This method is a template method for concrete classes. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XParamListParam + */ + public XParamListParam createXParamListParam(URL url) throws IOException, SAXException, ParserConfigurationException { + XParamListParam xParamListParam_ = createXParamListParam(); + xParamListParam_.setup(UJAXP.getDocument(url, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xParamListParam_); + } + + /** + * Creates a XHeadGlobal by the URL url. + * This method is a template method for concrete classes. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHeadGlobal + */ + public XHeadGlobal createXHeadGlobal(URL url) throws IOException, SAXException, ParserConfigurationException { + XHeadGlobal xHeadGlobal_ = createXHeadGlobal(); + xHeadGlobal_.setup(UJAXP.getDocument(url, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xHeadGlobal_); + } + + /** + * Creates a XHeadLocal by the URL url. + * This method is a template method for concrete classes. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHeadLocal + */ + public XHeadLocal createXHeadLocal(URL url) throws IOException, SAXException, ParserConfigurationException { + XHeadLocal xHeadLocal_ = createXHeadLocal(); + xHeadLocal_.setup(UJAXP.getDocument(url, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xHeadLocal_); + } + + /** + * Creates a XHead by the URL url. + * This method is a template method for concrete classes. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHead + */ + public XHead createXHead(URL url) throws IOException, SAXException, ParserConfigurationException { + XHead xHead_ = createXHead(); + xHead_.setup(UJAXP.getDocument(url, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xHead_); + } + + /** + * Creates a XGlyphFile by the URL url. + * This method is a template method for concrete classes. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XGlyphFile + */ + public XGlyphFile createXGlyphFile(URL url) throws IOException, SAXException, ParserConfigurationException { + XGlyphFile xGlyphFile_ = createXGlyphFile(); + xGlyphFile_.setup(UJAXP.getDocument(url, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xGlyphFile_); + } + + /** + * Creates a XContour by the URL url. + * This method is a template method for concrete classes. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XContour + */ + public XContour createXContour(URL url) throws IOException, SAXException, ParserConfigurationException { + XContour xContour_ = createXContour(); + xContour_.setup(UJAXP.getDocument(url, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xContour_); + } + + /** + * Creates a XPoint2d by the URL url. + * This method is a template method for concrete classes. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XPoint2d + */ + public XPoint2d createXPoint2d(URL url) throws IOException, SAXException, ParserConfigurationException { + XPoint2d xPoint2d_ = createXPoint2d(); + xPoint2d_.setup(UJAXP.getDocument(url, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xPoint2d_); + } + + /** + * Creates a XInvokePos by the URL url. + * This method is a template method for concrete classes. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokePos + */ + public XInvokePos createXInvokePos(URL url) throws IOException, SAXException, ParserConfigurationException { + XInvokePos xInvokePos_ = createXInvokePos(); + xInvokePos_.setup(UJAXP.getDocument(url, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xInvokePos_); + } + + /** + * Creates a XInvokeArg by the URL url. + * This method is a template method for concrete classes. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokeArg + */ + public XInvokeArg createXInvokeArg(URL url) throws IOException, SAXException, ParserConfigurationException { + XInvokeArg xInvokeArg_ = createXInvokeArg(); + xInvokeArg_.setup(UJAXP.getDocument(url, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xInvokeArg_); + } + + /** + * Creates a XInvokeVarg by the URL url. + * This method is a template method for concrete classes. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokeVarg + */ + public XInvokeVarg createXInvokeVarg(URL url) throws IOException, SAXException, ParserConfigurationException { + XInvokeVarg xInvokeVarg_ = createXInvokeVarg(); + xInvokeVarg_.setup(UJAXP.getDocument(url, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xInvokeVarg_); + } + + /** + * Creates a XInvoke by the URL url. + * This method is a template method for concrete classes. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvoke + */ + public XInvoke createXInvoke(URL url) throws IOException, SAXException, ParserConfigurationException { + XInvoke xInvoke_ = createXInvoke(); + xInvoke_.setup(UJAXP.getDocument(url, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xInvoke_); + } + + /** + * Creates a XInclude by the URL url. + * This method is a template method for concrete classes. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInclude + */ + public XInclude createXInclude(URL url) throws IOException, SAXException, ParserConfigurationException { + XInclude xInclude_ = createXInclude(); + xInclude_.setup(UJAXP.getDocument(url, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xInclude_); + } + + /** + * Creates a XModule by the URL url. + * This method is a template method for concrete classes. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XModule + */ + public XModule createXModule(URL url) throws IOException, SAXException, ParserConfigurationException { + XModule xModule_ = createXModule(); + xModule_.setup(UJAXP.getDocument(url, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xModule_); + } + + /** + * Creates a XBody by the URL url. + * This method is a template method for concrete classes. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XBody + */ + public XBody createXBody(URL url) throws IOException, SAXException, ParserConfigurationException { + XBody xBody_ = createXBody(); + xBody_.setup(UJAXP.getDocument(url, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xBody_); + } + + /** + * Creates a XStartGlyphElement by the URL url. + * This method is a template method for concrete classes. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XStartGlyphElement + */ + public XStartGlyphElement createXStartGlyphElement(URL url) throws IOException, SAXException, ParserConfigurationException { + XStartGlyphElement xStartGlyphElement_ = createXStartGlyphElement(); + xStartGlyphElement_.setup(UJAXP.getDocument(url, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xStartGlyphElement_); + } + + /** + * Creates a XControlPoint by the URL url. + * This method is a template method for concrete classes. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XControlPoint + */ + public XControlPoint createXControlPoint(URL url) throws IOException, SAXException, ParserConfigurationException { + XControlPoint xControlPoint_ = createXControlPoint(); + xControlPoint_.setup(UJAXP.getDocument(url, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xControlPoint_); + } + + /** + * Creates a XHint by the URL url. + * This method is a template method for concrete classes. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHint + */ + public XHint createXHint(URL url) throws IOException, SAXException, ParserConfigurationException { + XHint xHint_ = createXHint(); + xHint_.setup(UJAXP.getDocument(url, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xHint_); + } + + /** + * Creates a XContourPoint by the URL url. + * This method is a template method for concrete classes. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XContourPoint + */ + public XContourPoint createXContourPoint(URL url) throws IOException, SAXException, ParserConfigurationException { + XContourPoint xContourPoint_ = createXContourPoint(); + xContourPoint_.setup(UJAXP.getDocument(url, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xContourPoint_); + } + + /** + * Creates a XParamListParam by the InputStream in. + * This method is a template method for concrete classes. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XParamListParam + */ + public XParamListParam createXParamListParam(InputStream in) throws IOException, SAXException, ParserConfigurationException { + XParamListParam xParamListParam_ = createXParamListParam(); + xParamListParam_.setup(UJAXP.getDocument(in, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xParamListParam_); + } + + /** + * Creates a XHeadGlobal by the InputStream in. + * This method is a template method for concrete classes. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHeadGlobal + */ + public XHeadGlobal createXHeadGlobal(InputStream in) throws IOException, SAXException, ParserConfigurationException { + XHeadGlobal xHeadGlobal_ = createXHeadGlobal(); + xHeadGlobal_.setup(UJAXP.getDocument(in, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xHeadGlobal_); + } + + /** + * Creates a XHeadLocal by the InputStream in. + * This method is a template method for concrete classes. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHeadLocal + */ + public XHeadLocal createXHeadLocal(InputStream in) throws IOException, SAXException, ParserConfigurationException { + XHeadLocal xHeadLocal_ = createXHeadLocal(); + xHeadLocal_.setup(UJAXP.getDocument(in, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xHeadLocal_); + } + + /** + * Creates a XHead by the InputStream in. + * This method is a template method for concrete classes. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHead + */ + public XHead createXHead(InputStream in) throws IOException, SAXException, ParserConfigurationException { + XHead xHead_ = createXHead(); + xHead_.setup(UJAXP.getDocument(in, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xHead_); + } + + /** + * Creates a XGlyphFile by the InputStream in. + * This method is a template method for concrete classes. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XGlyphFile + */ + public XGlyphFile createXGlyphFile(InputStream in) throws IOException, SAXException, ParserConfigurationException { + XGlyphFile xGlyphFile_ = createXGlyphFile(); + xGlyphFile_.setup(UJAXP.getDocument(in, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xGlyphFile_); + } + + /** + * Creates a XContour by the InputStream in. + * This method is a template method for concrete classes. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XContour + */ + public XContour createXContour(InputStream in) throws IOException, SAXException, ParserConfigurationException { + XContour xContour_ = createXContour(); + xContour_.setup(UJAXP.getDocument(in, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xContour_); + } + + /** + * Creates a XPoint2d by the InputStream in. + * This method is a template method for concrete classes. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XPoint2d + */ + public XPoint2d createXPoint2d(InputStream in) throws IOException, SAXException, ParserConfigurationException { + XPoint2d xPoint2d_ = createXPoint2d(); + xPoint2d_.setup(UJAXP.getDocument(in, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xPoint2d_); + } + + /** + * Creates a XInvokePos by the InputStream in. + * This method is a template method for concrete classes. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokePos + */ + public XInvokePos createXInvokePos(InputStream in) throws IOException, SAXException, ParserConfigurationException { + XInvokePos xInvokePos_ = createXInvokePos(); + xInvokePos_.setup(UJAXP.getDocument(in, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xInvokePos_); + } + + /** + * Creates a XInvokeArg by the InputStream in. + * This method is a template method for concrete classes. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokeArg + */ + public XInvokeArg createXInvokeArg(InputStream in) throws IOException, SAXException, ParserConfigurationException { + XInvokeArg xInvokeArg_ = createXInvokeArg(); + xInvokeArg_.setup(UJAXP.getDocument(in, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xInvokeArg_); + } + + /** + * Creates a XInvokeVarg by the InputStream in. + * This method is a template method for concrete classes. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokeVarg + */ + public XInvokeVarg createXInvokeVarg(InputStream in) throws IOException, SAXException, ParserConfigurationException { + XInvokeVarg xInvokeVarg_ = createXInvokeVarg(); + xInvokeVarg_.setup(UJAXP.getDocument(in, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xInvokeVarg_); + } + + /** + * Creates a XInvoke by the InputStream in. + * This method is a template method for concrete classes. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvoke + */ + public XInvoke createXInvoke(InputStream in) throws IOException, SAXException, ParserConfigurationException { + XInvoke xInvoke_ = createXInvoke(); + xInvoke_.setup(UJAXP.getDocument(in, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xInvoke_); + } + + /** + * Creates a XInclude by the InputStream in. + * This method is a template method for concrete classes. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInclude + */ + public XInclude createXInclude(InputStream in) throws IOException, SAXException, ParserConfigurationException { + XInclude xInclude_ = createXInclude(); + xInclude_.setup(UJAXP.getDocument(in, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xInclude_); + } + + /** + * Creates a XModule by the InputStream in. + * This method is a template method for concrete classes. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XModule + */ + public XModule createXModule(InputStream in) throws IOException, SAXException, ParserConfigurationException { + XModule xModule_ = createXModule(); + xModule_.setup(UJAXP.getDocument(in, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xModule_); + } + + /** + * Creates a XBody by the InputStream in. + * This method is a template method for concrete classes. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XBody + */ + public XBody createXBody(InputStream in) throws IOException, SAXException, ParserConfigurationException { + XBody xBody_ = createXBody(); + xBody_.setup(UJAXP.getDocument(in, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xBody_); + } + + /** + * Creates a XStartGlyphElement by the InputStream in. + * This method is a template method for concrete classes. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XStartGlyphElement + */ + public XStartGlyphElement createXStartGlyphElement(InputStream in) throws IOException, SAXException, ParserConfigurationException { + XStartGlyphElement xStartGlyphElement_ = createXStartGlyphElement(); + xStartGlyphElement_.setup(UJAXP.getDocument(in, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xStartGlyphElement_); + } + + /** + * Creates a XControlPoint by the InputStream in. + * This method is a template method for concrete classes. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XControlPoint + */ + public XControlPoint createXControlPoint(InputStream in) throws IOException, SAXException, ParserConfigurationException { + XControlPoint xControlPoint_ = createXControlPoint(); + xControlPoint_.setup(UJAXP.getDocument(in, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xControlPoint_); + } + + /** + * Creates a XHint by the InputStream in. + * This method is a template method for concrete classes. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHint + */ + public XHint createXHint(InputStream in) throws IOException, SAXException, ParserConfigurationException { + XHint xHint_ = createXHint(); + xHint_.setup(UJAXP.getDocument(in, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xHint_); + } + + /** + * Creates a XContourPoint by the InputStream in. + * This method is a template method for concrete classes. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XContourPoint + */ + public XContourPoint createXContourPoint(InputStream in) throws IOException, SAXException, ParserConfigurationException { + XContourPoint xContourPoint_ = createXContourPoint(); + xContourPoint_.setup(UJAXP.getDocument(in, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xContourPoint_); + } + + /** + * Creates a XParamListParam by the InputSource is. + * This method is a template method for concrete classes. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XParamListParam + */ + public XParamListParam createXParamListParam(InputSource is) throws IOException, SAXException, ParserConfigurationException { + XParamListParam xParamListParam_ = createXParamListParam(); + xParamListParam_.setup(UJAXP.getDocument(is, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xParamListParam_); + } + + /** + * Creates a XHeadGlobal by the InputSource is. + * This method is a template method for concrete classes. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHeadGlobal + */ + public XHeadGlobal createXHeadGlobal(InputSource is) throws IOException, SAXException, ParserConfigurationException { + XHeadGlobal xHeadGlobal_ = createXHeadGlobal(); + xHeadGlobal_.setup(UJAXP.getDocument(is, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xHeadGlobal_); + } + + /** + * Creates a XHeadLocal by the InputSource is. + * This method is a template method for concrete classes. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHeadLocal + */ + public XHeadLocal createXHeadLocal(InputSource is) throws IOException, SAXException, ParserConfigurationException { + XHeadLocal xHeadLocal_ = createXHeadLocal(); + xHeadLocal_.setup(UJAXP.getDocument(is, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xHeadLocal_); + } + + /** + * Creates a XHead by the InputSource is. + * This method is a template method for concrete classes. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHead + */ + public XHead createXHead(InputSource is) throws IOException, SAXException, ParserConfigurationException { + XHead xHead_ = createXHead(); + xHead_.setup(UJAXP.getDocument(is, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xHead_); + } + + /** + * Creates a XGlyphFile by the InputSource is. + * This method is a template method for concrete classes. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XGlyphFile + */ + public XGlyphFile createXGlyphFile(InputSource is) throws IOException, SAXException, ParserConfigurationException { + XGlyphFile xGlyphFile_ = createXGlyphFile(); + xGlyphFile_.setup(UJAXP.getDocument(is, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xGlyphFile_); + } + + /** + * Creates a XContour by the InputSource is. + * This method is a template method for concrete classes. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XContour + */ + public XContour createXContour(InputSource is) throws IOException, SAXException, ParserConfigurationException { + XContour xContour_ = createXContour(); + xContour_.setup(UJAXP.getDocument(is, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xContour_); + } + + /** + * Creates a XPoint2d by the InputSource is. + * This method is a template method for concrete classes. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XPoint2d + */ + public XPoint2d createXPoint2d(InputSource is) throws IOException, SAXException, ParserConfigurationException { + XPoint2d xPoint2d_ = createXPoint2d(); + xPoint2d_.setup(UJAXP.getDocument(is, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xPoint2d_); + } + + /** + * Creates a XInvokePos by the InputSource is. + * This method is a template method for concrete classes. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokePos + */ + public XInvokePos createXInvokePos(InputSource is) throws IOException, SAXException, ParserConfigurationException { + XInvokePos xInvokePos_ = createXInvokePos(); + xInvokePos_.setup(UJAXP.getDocument(is, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xInvokePos_); + } + + /** + * Creates a XInvokeArg by the InputSource is. + * This method is a template method for concrete classes. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokeArg + */ + public XInvokeArg createXInvokeArg(InputSource is) throws IOException, SAXException, ParserConfigurationException { + XInvokeArg xInvokeArg_ = createXInvokeArg(); + xInvokeArg_.setup(UJAXP.getDocument(is, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xInvokeArg_); + } + + /** + * Creates a XInvokeVarg by the InputSource is. + * This method is a template method for concrete classes. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokeVarg + */ + public XInvokeVarg createXInvokeVarg(InputSource is) throws IOException, SAXException, ParserConfigurationException { + XInvokeVarg xInvokeVarg_ = createXInvokeVarg(); + xInvokeVarg_.setup(UJAXP.getDocument(is, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xInvokeVarg_); + } + + /** + * Creates a XInvoke by the InputSource is. + * This method is a template method for concrete classes. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvoke + */ + public XInvoke createXInvoke(InputSource is) throws IOException, SAXException, ParserConfigurationException { + XInvoke xInvoke_ = createXInvoke(); + xInvoke_.setup(UJAXP.getDocument(is, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xInvoke_); + } + + /** + * Creates a XInclude by the InputSource is. + * This method is a template method for concrete classes. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInclude + */ + public XInclude createXInclude(InputSource is) throws IOException, SAXException, ParserConfigurationException { + XInclude xInclude_ = createXInclude(); + xInclude_.setup(UJAXP.getDocument(is, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xInclude_); + } + + /** + * Creates a XModule by the InputSource is. + * This method is a template method for concrete classes. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XModule + */ + public XModule createXModule(InputSource is) throws IOException, SAXException, ParserConfigurationException { + XModule xModule_ = createXModule(); + xModule_.setup(UJAXP.getDocument(is, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xModule_); + } + + /** + * Creates a XBody by the InputSource is. + * This method is a template method for concrete classes. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XBody + */ + public XBody createXBody(InputSource is) throws IOException, SAXException, ParserConfigurationException { + XBody xBody_ = createXBody(); + xBody_.setup(UJAXP.getDocument(is, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xBody_); + } + + /** + * Creates a XStartGlyphElement by the InputSource is. + * This method is a template method for concrete classes. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XStartGlyphElement + */ + public XStartGlyphElement createXStartGlyphElement(InputSource is) throws IOException, SAXException, ParserConfigurationException { + XStartGlyphElement xStartGlyphElement_ = createXStartGlyphElement(); + xStartGlyphElement_.setup(UJAXP.getDocument(is, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xStartGlyphElement_); + } + + /** + * Creates a XControlPoint by the InputSource is. + * This method is a template method for concrete classes. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XControlPoint + */ + public XControlPoint createXControlPoint(InputSource is) throws IOException, SAXException, ParserConfigurationException { + XControlPoint xControlPoint_ = createXControlPoint(); + xControlPoint_.setup(UJAXP.getDocument(is, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xControlPoint_); + } + + /** + * Creates a XHint by the InputSource is. + * This method is a template method for concrete classes. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHint + */ + public XHint createXHint(InputSource is) throws IOException, SAXException, ParserConfigurationException { + XHint xHint_ = createXHint(); + xHint_.setup(UJAXP.getDocument(is, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xHint_); + } + + /** + * Creates a XContourPoint by the InputSource is. + * This method is a template method for concrete classes. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XContourPoint + */ + public XContourPoint createXContourPoint(InputSource is) throws IOException, SAXException, ParserConfigurationException { + XContourPoint xContourPoint_ = createXContourPoint(); + xContourPoint_.setup(UJAXP.getDocument(is, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xContourPoint_); + } + + /** + * Creates a XParamListParam by the Reader reader. + * This method is a template method for concrete classes. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XParamListParam + */ + public XParamListParam createXParamListParam(Reader reader) throws IOException, SAXException, ParserConfigurationException { + XParamListParam xParamListParam_ = createXParamListParam(); + xParamListParam_.setup(UJAXP.getDocument(reader, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xParamListParam_); + } + + /** + * Creates a XHeadGlobal by the Reader reader. + * This method is a template method for concrete classes. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHeadGlobal + */ + public XHeadGlobal createXHeadGlobal(Reader reader) throws IOException, SAXException, ParserConfigurationException { + XHeadGlobal xHeadGlobal_ = createXHeadGlobal(); + xHeadGlobal_.setup(UJAXP.getDocument(reader, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xHeadGlobal_); + } + + /** + * Creates a XHeadLocal by the Reader reader. + * This method is a template method for concrete classes. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHeadLocal + */ + public XHeadLocal createXHeadLocal(Reader reader) throws IOException, SAXException, ParserConfigurationException { + XHeadLocal xHeadLocal_ = createXHeadLocal(); + xHeadLocal_.setup(UJAXP.getDocument(reader, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xHeadLocal_); + } + + /** + * Creates a XHead by the Reader reader. + * This method is a template method for concrete classes. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHead + */ + public XHead createXHead(Reader reader) throws IOException, SAXException, ParserConfigurationException { + XHead xHead_ = createXHead(); + xHead_.setup(UJAXP.getDocument(reader, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xHead_); + } + + /** + * Creates a XGlyphFile by the Reader reader. + * This method is a template method for concrete classes. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XGlyphFile + */ + public XGlyphFile createXGlyphFile(Reader reader) throws IOException, SAXException, ParserConfigurationException { + XGlyphFile xGlyphFile_ = createXGlyphFile(); + xGlyphFile_.setup(UJAXP.getDocument(reader, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xGlyphFile_); + } + + /** + * Creates a XContour by the Reader reader. + * This method is a template method for concrete classes. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XContour + */ + public XContour createXContour(Reader reader) throws IOException, SAXException, ParserConfigurationException { + XContour xContour_ = createXContour(); + xContour_.setup(UJAXP.getDocument(reader, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xContour_); + } + + /** + * Creates a XPoint2d by the Reader reader. + * This method is a template method for concrete classes. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XPoint2d + */ + public XPoint2d createXPoint2d(Reader reader) throws IOException, SAXException, ParserConfigurationException { + XPoint2d xPoint2d_ = createXPoint2d(); + xPoint2d_.setup(UJAXP.getDocument(reader, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xPoint2d_); + } + + /** + * Creates a XInvokePos by the Reader reader. + * This method is a template method for concrete classes. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokePos + */ + public XInvokePos createXInvokePos(Reader reader) throws IOException, SAXException, ParserConfigurationException { + XInvokePos xInvokePos_ = createXInvokePos(); + xInvokePos_.setup(UJAXP.getDocument(reader, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xInvokePos_); + } + + /** + * Creates a XInvokeArg by the Reader reader. + * This method is a template method for concrete classes. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokeArg + */ + public XInvokeArg createXInvokeArg(Reader reader) throws IOException, SAXException, ParserConfigurationException { + XInvokeArg xInvokeArg_ = createXInvokeArg(); + xInvokeArg_.setup(UJAXP.getDocument(reader, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xInvokeArg_); + } + + /** + * Creates a XInvokeVarg by the Reader reader. + * This method is a template method for concrete classes. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokeVarg + */ + public XInvokeVarg createXInvokeVarg(Reader reader) throws IOException, SAXException, ParserConfigurationException { + XInvokeVarg xInvokeVarg_ = createXInvokeVarg(); + xInvokeVarg_.setup(UJAXP.getDocument(reader, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xInvokeVarg_); + } + + /** + * Creates a XInvoke by the Reader reader. + * This method is a template method for concrete classes. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvoke + */ + public XInvoke createXInvoke(Reader reader) throws IOException, SAXException, ParserConfigurationException { + XInvoke xInvoke_ = createXInvoke(); + xInvoke_.setup(UJAXP.getDocument(reader, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xInvoke_); + } + + /** + * Creates a XInclude by the Reader reader. + * This method is a template method for concrete classes. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInclude + */ + public XInclude createXInclude(Reader reader) throws IOException, SAXException, ParserConfigurationException { + XInclude xInclude_ = createXInclude(); + xInclude_.setup(UJAXP.getDocument(reader, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xInclude_); + } + + /** + * Creates a XModule by the Reader reader. + * This method is a template method for concrete classes. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XModule + */ + public XModule createXModule(Reader reader) throws IOException, SAXException, ParserConfigurationException { + XModule xModule_ = createXModule(); + xModule_.setup(UJAXP.getDocument(reader, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xModule_); + } + + /** + * Creates a XBody by the Reader reader. + * This method is a template method for concrete classes. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XBody + */ + public XBody createXBody(Reader reader) throws IOException, SAXException, ParserConfigurationException { + XBody xBody_ = createXBody(); + xBody_.setup(UJAXP.getDocument(reader, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xBody_); + } + + /** + * Creates a XStartGlyphElement by the Reader reader. + * This method is a template method for concrete classes. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XStartGlyphElement + */ + public XStartGlyphElement createXStartGlyphElement(Reader reader) throws IOException, SAXException, ParserConfigurationException { + XStartGlyphElement xStartGlyphElement_ = createXStartGlyphElement(); + xStartGlyphElement_.setup(UJAXP.getDocument(reader, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xStartGlyphElement_); + } + + /** + * Creates a XControlPoint by the Reader reader. + * This method is a template method for concrete classes. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XControlPoint + */ + public XControlPoint createXControlPoint(Reader reader) throws IOException, SAXException, ParserConfigurationException { + XControlPoint xControlPoint_ = createXControlPoint(); + xControlPoint_.setup(UJAXP.getDocument(reader, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xControlPoint_); + } + + /** + * Creates a XHint by the Reader reader. + * This method is a template method for concrete classes. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHint + */ + public XHint createXHint(Reader reader) throws IOException, SAXException, ParserConfigurationException { + XHint xHint_ = createXHint(); + xHint_.setup(UJAXP.getDocument(reader, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xHint_); + } + + /** + * Creates a XContourPoint by the Reader reader. + * This method is a template method for concrete classes. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XContourPoint + */ + public XContourPoint createXContourPoint(Reader reader) throws IOException, SAXException, ParserConfigurationException { + XContourPoint xContourPoint_ = createXContourPoint(); + xContourPoint_.setup(UJAXP.getDocument(reader, UJAXP.FLAG_NONE, errorHandler, entityResolver)); + return (xContourPoint_); + } + + /** + * Creates a XParamListParam by the object source. + * This method is a template method for concrete classes. + * + * @param source + * @return XParamListParam + */ + public XParamListParam createXParamListParam(XParamListParam source) { + XParamListParam xParamListParam_ = createXParamListParam(); + xParamListParam_.setup(source); + return (xParamListParam_); + } + + /** + * Creates a XHeadGlobal by the object source. + * This method is a template method for concrete classes. + * + * @param source + * @return XHeadGlobal + */ + public XHeadGlobal createXHeadGlobal(XHeadGlobal source) { + XHeadGlobal xHeadGlobal_ = createXHeadGlobal(); + xHeadGlobal_.setup(source); + return (xHeadGlobal_); + } + + /** + * Creates a XHeadLocal by the object source. + * This method is a template method for concrete classes. + * + * @param source + * @return XHeadLocal + */ + public XHeadLocal createXHeadLocal(XHeadLocal source) { + XHeadLocal xHeadLocal_ = createXHeadLocal(); + xHeadLocal_.setup(source); + return (xHeadLocal_); + } + + /** + * Creates a XHead by the object source. + * This method is a template method for concrete classes. + * + * @param source + * @return XHead + */ + public XHead createXHead(XHead source) { + XHead xHead_ = createXHead(); + xHead_.setup(source); + return (xHead_); + } + + /** + * Creates a XGlyphFile by the object source. + * This method is a template method for concrete classes. + * + * @param source + * @return XGlyphFile + */ + public XGlyphFile createXGlyphFile(XGlyphFile source) { + XGlyphFile xGlyphFile_ = createXGlyphFile(); + xGlyphFile_.setup(source); + return (xGlyphFile_); + } + + /** + * Creates a XContour by the object source. + * This method is a template method for concrete classes. + * + * @param source + * @return XContour + */ + public XContour createXContour(XContour source) { + XContour xContour_ = createXContour(); + xContour_.setup(source); + return (xContour_); + } + + /** + * Creates a XPoint2d by the object source. + * This method is a template method for concrete classes. + * + * @param source + * @return XPoint2d + */ + public XPoint2d createXPoint2d(XPoint2d source) { + XPoint2d xPoint2d_ = createXPoint2d(); + xPoint2d_.setup(source); + return (xPoint2d_); + } + + /** + * Creates a XInvokePos by the object source. + * This method is a template method for concrete classes. + * + * @param source + * @return XInvokePos + */ + public XInvokePos createXInvokePos(XInvokePos source) { + XInvokePos xInvokePos_ = createXInvokePos(); + xInvokePos_.setup(source); + return (xInvokePos_); + } + + /** + * Creates a XInvokeArg by the object source. + * This method is a template method for concrete classes. + * + * @param source + * @return XInvokeArg + */ + public XInvokeArg createXInvokeArg(XInvokeArg source) { + XInvokeArg xInvokeArg_ = createXInvokeArg(); + xInvokeArg_.setup(source); + return (xInvokeArg_); + } + + /** + * Creates a XInvokeVarg by the object source. + * This method is a template method for concrete classes. + * + * @param source + * @return XInvokeVarg + */ + public XInvokeVarg createXInvokeVarg(XInvokeVarg source) { + XInvokeVarg xInvokeVarg_ = createXInvokeVarg(); + xInvokeVarg_.setup(source); + return (xInvokeVarg_); + } + + /** + * Creates a XInvoke by the object source. + * This method is a template method for concrete classes. + * + * @param source + * @return XInvoke + */ + public XInvoke createXInvoke(XInvoke source) { + XInvoke xInvoke_ = createXInvoke(); + xInvoke_.setup(source); + return (xInvoke_); + } + + /** + * Creates a XInclude by the object source. + * This method is a template method for concrete classes. + * + * @param source + * @return XInclude + */ + public XInclude createXInclude(XInclude source) { + XInclude xInclude_ = createXInclude(); + xInclude_.setup(source); + return (xInclude_); + } + + /** + * Creates a XModule by the object source. + * This method is a template method for concrete classes. + * + * @param source + * @return XModule + */ + public XModule createXModule(XModule source) { + XModule xModule_ = createXModule(); + xModule_.setup(source); + return (xModule_); + } + + /** + * Creates a XBody by the object source. + * This method is a template method for concrete classes. + * + * @param source + * @return XBody + */ + public XBody createXBody(XBody source) { + XBody xBody_ = createXBody(); + xBody_.setup(source); + return (xBody_); + } + + /** + * Creates a XStartGlyphElement by the object source. + * This method is a template method for concrete classes. + * + * @param source + * @return XStartGlyphElement + */ + public XStartGlyphElement createXStartGlyphElement(XStartGlyphElement source) { + XStartGlyphElement xStartGlyphElement_ = createXStartGlyphElement(); + xStartGlyphElement_.setup(source); + return (xStartGlyphElement_); + } + + /** + * Creates a XControlPoint by the object source. + * This method is a template method for concrete classes. + * + * @param source + * @return XControlPoint + */ + public XControlPoint createXControlPoint(XControlPoint source) { + XControlPoint xControlPoint_ = createXControlPoint(); + xControlPoint_.setup(source); + return (xControlPoint_); + } + + /** + * Creates a XHint by the object source. + * This method is a template method for concrete classes. + * + * @param source + * @return XHint + */ + public XHint createXHint(XHint source) { + XHint xHint_ = createXHint(); + xHint_.setup(source); + return (xHint_); + } + + /** + * Creates a XContourPoint by the object source. + * This method is a template method for concrete classes. + * + * @param source + * @return XContourPoint + */ + public XContourPoint createXContourPoint(XContourPoint source) { + XContourPoint xContourPoint_ = createXContourPoint(); + xContourPoint_.setup(source); + return (xContourPoint_); + } + + /** + * Creates a XParamListParam by the Document doc. + * This method is a template method for concrete classes. + * + * @param doc + * @return XParamListParam + */ + public XParamListParam createXParamListParam(Document doc) { + XParamListParam xParamListParam_ = createXParamListParam(); + xParamListParam_.setup(doc); + return (xParamListParam_); + } + + /** + * Creates a XHeadGlobal by the Document doc. + * This method is a template method for concrete classes. + * + * @param doc + * @return XHeadGlobal + */ + public XHeadGlobal createXHeadGlobal(Document doc) { + XHeadGlobal xHeadGlobal_ = createXHeadGlobal(); + xHeadGlobal_.setup(doc); + return (xHeadGlobal_); + } + + /** + * Creates a XHeadLocal by the Document doc. + * This method is a template method for concrete classes. + * + * @param doc + * @return XHeadLocal + */ + public XHeadLocal createXHeadLocal(Document doc) { + XHeadLocal xHeadLocal_ = createXHeadLocal(); + xHeadLocal_.setup(doc); + return (xHeadLocal_); + } + + /** + * Creates a XHead by the Document doc. + * This method is a template method for concrete classes. + * + * @param doc + * @return XHead + */ + public XHead createXHead(Document doc) { + XHead xHead_ = createXHead(); + xHead_.setup(doc); + return (xHead_); + } + + /** + * Creates a XGlyphFile by the Document doc. + * This method is a template method for concrete classes. + * + * @param doc + * @return XGlyphFile + */ + public XGlyphFile createXGlyphFile(Document doc) { + XGlyphFile xGlyphFile_ = createXGlyphFile(); + xGlyphFile_.setup(doc); + return (xGlyphFile_); + } + + /** + * Creates a XContour by the Document doc. + * This method is a template method for concrete classes. + * + * @param doc + * @return XContour + */ + public XContour createXContour(Document doc) { + XContour xContour_ = createXContour(); + xContour_.setup(doc); + return (xContour_); + } + + /** + * Creates a XPoint2d by the Document doc. + * This method is a template method for concrete classes. + * + * @param doc + * @return XPoint2d + */ + public XPoint2d createXPoint2d(Document doc) { + XPoint2d xPoint2d_ = createXPoint2d(); + xPoint2d_.setup(doc); + return (xPoint2d_); + } + + /** + * Creates a XInvokePos by the Document doc. + * This method is a template method for concrete classes. + * + * @param doc + * @return XInvokePos + */ + public XInvokePos createXInvokePos(Document doc) { + XInvokePos xInvokePos_ = createXInvokePos(); + xInvokePos_.setup(doc); + return (xInvokePos_); + } + + /** + * Creates a XInvokeArg by the Document doc. + * This method is a template method for concrete classes. + * + * @param doc + * @return XInvokeArg + */ + public XInvokeArg createXInvokeArg(Document doc) { + XInvokeArg xInvokeArg_ = createXInvokeArg(); + xInvokeArg_.setup(doc); + return (xInvokeArg_); + } + + /** + * Creates a XInvokeVarg by the Document doc. + * This method is a template method for concrete classes. + * + * @param doc + * @return XInvokeVarg + */ + public XInvokeVarg createXInvokeVarg(Document doc) { + XInvokeVarg xInvokeVarg_ = createXInvokeVarg(); + xInvokeVarg_.setup(doc); + return (xInvokeVarg_); + } + + /** + * Creates a XInvoke by the Document doc. + * This method is a template method for concrete classes. + * + * @param doc + * @return XInvoke + */ + public XInvoke createXInvoke(Document doc) { + XInvoke xInvoke_ = createXInvoke(); + xInvoke_.setup(doc); + return (xInvoke_); + } + + /** + * Creates a XInclude by the Document doc. + * This method is a template method for concrete classes. + * + * @param doc + * @return XInclude + */ + public XInclude createXInclude(Document doc) { + XInclude xInclude_ = createXInclude(); + xInclude_.setup(doc); + return (xInclude_); + } + + /** + * Creates a XModule by the Document doc. + * This method is a template method for concrete classes. + * + * @param doc + * @return XModule + */ + public XModule createXModule(Document doc) { + XModule xModule_ = createXModule(); + xModule_.setup(doc); + return (xModule_); + } + + /** + * Creates a XBody by the Document doc. + * This method is a template method for concrete classes. + * + * @param doc + * @return XBody + */ + public XBody createXBody(Document doc) { + XBody xBody_ = createXBody(); + xBody_.setup(doc); + return (xBody_); + } + + /** + * Creates a XStartGlyphElement by the Document doc. + * This method is a template method for concrete classes. + * + * @param doc + * @return XStartGlyphElement + */ + public XStartGlyphElement createXStartGlyphElement(Document doc) { + XStartGlyphElement xStartGlyphElement_ = createXStartGlyphElement(); + xStartGlyphElement_.setup(doc); + return (xStartGlyphElement_); + } + + /** + * Creates a XControlPoint by the Document doc. + * This method is a template method for concrete classes. + * + * @param doc + * @return XControlPoint + */ + public XControlPoint createXControlPoint(Document doc) { + XControlPoint xControlPoint_ = createXControlPoint(); + xControlPoint_.setup(doc); + return (xControlPoint_); + } + + /** + * Creates a XHint by the Document doc. + * This method is a template method for concrete classes. + * + * @param doc + * @return XHint + */ + public XHint createXHint(Document doc) { + XHint xHint_ = createXHint(); + xHint_.setup(doc); + return (xHint_); + } + + /** + * Creates a XContourPoint by the Document doc. + * This method is a template method for concrete classes. + * + * @param doc + * @return XContourPoint + */ + public XContourPoint createXContourPoint(Document doc) { + XContourPoint xContourPoint_ = createXContourPoint(); + xContourPoint_.setup(doc); + return (xContourPoint_); + } + + /** + * Creates a XParamListParam by the Element element. + * This method is a template method for concrete classes. + * + * @param element + * @return XParamListParam + */ + public XParamListParam createXParamListParam(Element element) { + XParamListParam xParamListParam_ = createXParamListParam(); + xParamListParam_.setup(element); + return (xParamListParam_); + } + + /** + * Creates a XHeadGlobal by the Element element. + * This method is a template method for concrete classes. + * + * @param element + * @return XHeadGlobal + */ + public XHeadGlobal createXHeadGlobal(Element element) { + XHeadGlobal xHeadGlobal_ = createXHeadGlobal(); + xHeadGlobal_.setup(element); + return (xHeadGlobal_); + } + + /** + * Creates a XHeadLocal by the Element element. + * This method is a template method for concrete classes. + * + * @param element + * @return XHeadLocal + */ + public XHeadLocal createXHeadLocal(Element element) { + XHeadLocal xHeadLocal_ = createXHeadLocal(); + xHeadLocal_.setup(element); + return (xHeadLocal_); + } + + /** + * Creates a XHead by the Element element. + * This method is a template method for concrete classes. + * + * @param element + * @return XHead + */ + public XHead createXHead(Element element) { + XHead xHead_ = createXHead(); + xHead_.setup(element); + return (xHead_); + } + + /** + * Creates a XGlyphFile by the Element element. + * This method is a template method for concrete classes. + * + * @param element + * @return XGlyphFile + */ + public XGlyphFile createXGlyphFile(Element element) { + XGlyphFile xGlyphFile_ = createXGlyphFile(); + xGlyphFile_.setup(element); + return (xGlyphFile_); + } + + /** + * Creates a XContour by the Element element. + * This method is a template method for concrete classes. + * + * @param element + * @return XContour + */ + public XContour createXContour(Element element) { + XContour xContour_ = createXContour(); + xContour_.setup(element); + return (xContour_); + } + + /** + * Creates a XPoint2d by the Element element. + * This method is a template method for concrete classes. + * + * @param element + * @return XPoint2d + */ + public XPoint2d createXPoint2d(Element element) { + XPoint2d xPoint2d_ = createXPoint2d(); + xPoint2d_.setup(element); + return (xPoint2d_); + } + + /** + * Creates a XInvokePos by the Element element. + * This method is a template method for concrete classes. + * + * @param element + * @return XInvokePos + */ + public XInvokePos createXInvokePos(Element element) { + XInvokePos xInvokePos_ = createXInvokePos(); + xInvokePos_.setup(element); + return (xInvokePos_); + } + + /** + * Creates a XInvokeArg by the Element element. + * This method is a template method for concrete classes. + * + * @param element + * @return XInvokeArg + */ + public XInvokeArg createXInvokeArg(Element element) { + XInvokeArg xInvokeArg_ = createXInvokeArg(); + xInvokeArg_.setup(element); + return (xInvokeArg_); + } + + /** + * Creates a XInvokeVarg by the Element element. + * This method is a template method for concrete classes. + * + * @param element + * @return XInvokeVarg + */ + public XInvokeVarg createXInvokeVarg(Element element) { + XInvokeVarg xInvokeVarg_ = createXInvokeVarg(); + xInvokeVarg_.setup(element); + return (xInvokeVarg_); + } + + /** + * Creates a XInvoke by the Element element. + * This method is a template method for concrete classes. + * + * @param element + * @return XInvoke + */ + public XInvoke createXInvoke(Element element) { + XInvoke xInvoke_ = createXInvoke(); + xInvoke_.setup(element); + return (xInvoke_); + } + + /** + * Creates a XInclude by the Element element. + * This method is a template method for concrete classes. + * + * @param element + * @return XInclude + */ + public XInclude createXInclude(Element element) { + XInclude xInclude_ = createXInclude(); + xInclude_.setup(element); + return (xInclude_); + } + + /** + * Creates a XModule by the Element element. + * This method is a template method for concrete classes. + * + * @param element + * @return XModule + */ + public XModule createXModule(Element element) { + XModule xModule_ = createXModule(); + xModule_.setup(element); + return (xModule_); + } + + /** + * Creates a XBody by the Element element. + * This method is a template method for concrete classes. + * + * @param element + * @return XBody + */ + public XBody createXBody(Element element) { + XBody xBody_ = createXBody(); + xBody_.setup(element); + return (xBody_); + } + + /** + * Creates a XStartGlyphElement by the Element element. + * This method is a template method for concrete classes. + * + * @param element + * @return XStartGlyphElement + */ + public XStartGlyphElement createXStartGlyphElement(Element element) { + XStartGlyphElement xStartGlyphElement_ = createXStartGlyphElement(); + xStartGlyphElement_.setup(element); + return (xStartGlyphElement_); + } + + /** + * Creates a XControlPoint by the Element element. + * This method is a template method for concrete classes. + * + * @param element + * @return XControlPoint + */ + public XControlPoint createXControlPoint(Element element) { + XControlPoint xControlPoint_ = createXControlPoint(); + xControlPoint_.setup(element); + return (xControlPoint_); + } + + /** + * Creates a XHint by the Element element. + * This method is a template method for concrete classes. + * + * @param element + * @return XHint + */ + public XHint createXHint(Element element) { + XHint xHint_ = createXHint(); + xHint_.setup(element); + return (xHint_); + } + + /** + * Creates a XContourPoint by the Element element. + * This method is a template method for concrete classes. + * + * @param element + * @return XContourPoint + */ + public XContourPoint createXContourPoint(Element element) { + XContourPoint xContourPoint_ = createXContourPoint(); + xContourPoint_.setup(element); + return (xContourPoint_); + } + + /** + * Creates a XParamListParam by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * This method is a template method for concrete classes. + * + * @param stack + * @return XParamListParam + */ + public XParamListParam createXParamListParam(RStack stack) { + XParamListParam xParamListParam_ = createXParamListParam(); + xParamListParam_.setup(stack); + return (xParamListParam_); + } + + /** + * Creates a XHeadGlobal by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * This method is a template method for concrete classes. + * + * @param stack + * @return XHeadGlobal + */ + public XHeadGlobal createXHeadGlobal(RStack stack) { + XHeadGlobal xHeadGlobal_ = createXHeadGlobal(); + xHeadGlobal_.setup(stack); + return (xHeadGlobal_); + } + + /** + * Creates a XHeadLocal by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * This method is a template method for concrete classes. + * + * @param stack + * @return XHeadLocal + */ + public XHeadLocal createXHeadLocal(RStack stack) { + XHeadLocal xHeadLocal_ = createXHeadLocal(); + xHeadLocal_.setup(stack); + return (xHeadLocal_); + } + + /** + * Creates a XHead by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * This method is a template method for concrete classes. + * + * @param stack + * @return XHead + */ + public XHead createXHead(RStack stack) { + XHead xHead_ = createXHead(); + xHead_.setup(stack); + return (xHead_); + } + + /** + * Creates a XGlyphFile by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * This method is a template method for concrete classes. + * + * @param stack + * @return XGlyphFile + */ + public XGlyphFile createXGlyphFile(RStack stack) { + XGlyphFile xGlyphFile_ = createXGlyphFile(); + xGlyphFile_.setup(stack); + return (xGlyphFile_); + } + + /** + * Creates a XContour by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * This method is a template method for concrete classes. + * + * @param stack + * @return XContour + */ + public XContour createXContour(RStack stack) { + XContour xContour_ = createXContour(); + xContour_.setup(stack); + return (xContour_); + } + + /** + * Creates a XPoint2d by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * This method is a template method for concrete classes. + * + * @param stack + * @return XPoint2d + */ + public XPoint2d createXPoint2d(RStack stack) { + XPoint2d xPoint2d_ = createXPoint2d(); + xPoint2d_.setup(stack); + return (xPoint2d_); + } + + /** + * Creates a XInvokePos by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * This method is a template method for concrete classes. + * + * @param stack + * @return XInvokePos + */ + public XInvokePos createXInvokePos(RStack stack) { + XInvokePos xInvokePos_ = createXInvokePos(); + xInvokePos_.setup(stack); + return (xInvokePos_); + } + + /** + * Creates a XInvokeArg by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * This method is a template method for concrete classes. + * + * @param stack + * @return XInvokeArg + */ + public XInvokeArg createXInvokeArg(RStack stack) { + XInvokeArg xInvokeArg_ = createXInvokeArg(); + xInvokeArg_.setup(stack); + return (xInvokeArg_); + } + + /** + * Creates a XInvokeVarg by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * This method is a template method for concrete classes. + * + * @param stack + * @return XInvokeVarg + */ + public XInvokeVarg createXInvokeVarg(RStack stack) { + XInvokeVarg xInvokeVarg_ = createXInvokeVarg(); + xInvokeVarg_.setup(stack); + return (xInvokeVarg_); + } + + /** + * Creates a XInvoke by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * This method is a template method for concrete classes. + * + * @param stack + * @return XInvoke + */ + public XInvoke createXInvoke(RStack stack) { + XInvoke xInvoke_ = createXInvoke(); + xInvoke_.setup(stack); + return (xInvoke_); + } + + /** + * Creates a XInclude by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * This method is a template method for concrete classes. + * + * @param stack + * @return XInclude + */ + public XInclude createXInclude(RStack stack) { + XInclude xInclude_ = createXInclude(); + xInclude_.setup(stack); + return (xInclude_); + } + + /** + * Creates a XModule by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * This method is a template method for concrete classes. + * + * @param stack + * @return XModule + */ + public XModule createXModule(RStack stack) { + XModule xModule_ = createXModule(); + xModule_.setup(stack); + return (xModule_); + } + + /** + * Creates a XBody by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * This method is a template method for concrete classes. + * + * @param stack + * @return XBody + */ + public XBody createXBody(RStack stack) { + XBody xBody_ = createXBody(); + xBody_.setup(stack); + return (xBody_); + } + + /** + * Creates a XStartGlyphElement by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * This method is a template method for concrete classes. + * + * @param stack + * @return XStartGlyphElement + */ + public XStartGlyphElement createXStartGlyphElement(RStack stack) { + XStartGlyphElement xStartGlyphElement_ = createXStartGlyphElement(); + xStartGlyphElement_.setup(stack); + return (xStartGlyphElement_); + } + + /** + * Creates a XControlPoint by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * This method is a template method for concrete classes. + * + * @param stack + * @return XControlPoint + */ + public XControlPoint createXControlPoint(RStack stack) { + XControlPoint xControlPoint_ = createXControlPoint(); + xControlPoint_.setup(stack); + return (xControlPoint_); + } + + /** + * Creates a XHint by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * This method is a template method for concrete classes. + * + * @param stack + * @return XHint + */ + public XHint createXHint(RStack stack) { + XHint xHint_ = createXHint(); + xHint_.setup(stack); + return (xHint_); + } + + /** + * Creates a XContourPoint by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * This method is a template method for concrete classes. + * + * @param stack + * @return XContourPoint + */ + public XContourPoint createXContourPoint(RStack stack) { + XContourPoint xContourPoint_ = createXContourPoint(); + xContourPoint_.setup(stack); + return (xContourPoint_); + } + + /** + * Creates a XParamList by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * This method is a template method for concrete classes. + * + * @param stack + * @return XParamList + */ + public XParamList createXParamList(RStack stack) { + XParamList xParamList_ = createXParamList(); + xParamList_.setup(stack); + return (xParamList_); + } + + /** + * Creates a XParamList by the object source. + * This method is a template method for concrete classes. + * + * @param source + * @return XParamList + */ + public XParamList createXParamList(XParamList source) { + XParamList xParamList_ = createXParamList(); + xParamList_.setup(source); + return (xParamList_); + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/xml/DefaultGlyphFactory.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/xml/DefaultGlyphFactory.java new file mode 100644 index 000000000..bf2d11249 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/xml/DefaultGlyphFactory.java @@ -0,0 +1,394 @@ +/* + * The Relaxer artifact + * Copyright (c) 2000-2004, ASAMI Tomoharu, All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package org.doubletype.ossa.xml; + +/** + * DefaultGlyphFactory is generated by Relaxer based on glyph.rng. + * + * @version glyph.rng 1.0 (Tue Nov 09 20:22:48 EST 2004) + * @author Relaxer 1.1b (http://www.relaxer.org) + */ +public class DefaultGlyphFactory extends AbstractGlyphFactory { + + /** + * Gets a Class of XParamListParam. + * + * @return Class + */ + public Class getXParamListParamClass() { + return (XParamListParam.class); + } + + /** + * Gets a Class of XHeadGlobal. + * + * @return Class + */ + public Class getXHeadGlobalClass() { + return (XHeadGlobal.class); + } + + /** + * Gets a Class of XHeadLocal. + * + * @return Class + */ + public Class getXHeadLocalClass() { + return (XHeadLocal.class); + } + + /** + * Gets a Class of XHead. + * + * @return Class + */ + public Class getXHeadClass() { + return (XHead.class); + } + + /** + * Gets a Class of XGlyphFile. + * + * @return Class + */ + public Class getXGlyphFileClass() { + return (XGlyphFile.class); + } + + /** + * Gets a Class of XContour. + * + * @return Class + */ + public Class getXContourClass() { + return (XContour.class); + } + + /** + * Gets a Class of XPoint2d. + * + * @return Class + */ + public Class getXPoint2dClass() { + return (XPoint2d.class); + } + + /** + * Gets a Class of XInvokePos. + * + * @return Class + */ + public Class getXInvokePosClass() { + return (XInvokePos.class); + } + + /** + * Gets a Class of XInvokeArg. + * + * @return Class + */ + public Class getXInvokeArgClass() { + return (XInvokeArg.class); + } + + /** + * Gets a Class of XInvokeVarg. + * + * @return Class + */ + public Class getXInvokeVargClass() { + return (XInvokeVarg.class); + } + + /** + * Gets a Class of XInvoke. + * + * @return Class + */ + public Class getXInvokeClass() { + return (XInvoke.class); + } + + /** + * Gets a Class of XInclude. + * + * @return Class + */ + public Class getXIncludeClass() { + return (XInclude.class); + } + + /** + * Gets a Class of XModule. + * + * @return Class + */ + public Class getXModuleClass() { + return (XModule.class); + } + + /** + * Gets a Class of XBody. + * + * @return Class + */ + public Class getXBodyClass() { + return (XBody.class); + } + + /** + * Gets a Class of XStartGlyphElement. + * + * @return Class + */ + public Class getXStartGlyphElementClass() { + return (XStartGlyphElement.class); + } + + /** + * Gets a Class of XControlPoint. + * + * @return Class + */ + public Class getXControlPointClass() { + return (XControlPoint.class); + } + + /** + * Gets a Class of XHint. + * + * @return Class + */ + public Class getXHintClass() { + return (XHint.class); + } + + /** + * Gets a Class of XContourPoint. + * + * @return Class + */ + public Class getXContourPointClass() { + return (XContourPoint.class); + } + + /** + * Gets a Class of XParamList. + * + * @return Class + */ + public Class getXParamListClass() { + return (XParamList.class); + } + + /** + * Creates a default XParamListParam. + * This method is a hook method of the AbstractGlyphFactory. + * + * @return XParamListParam + */ + public XParamListParam createXParamListParam() { + return (new XParamListParam()); + } + + /** + * Creates a default XHeadGlobal. + * This method is a hook method of the AbstractGlyphFactory. + * + * @return XHeadGlobal + */ + public XHeadGlobal createXHeadGlobal() { + return (new XHeadGlobal()); + } + + /** + * Creates a default XHeadLocal. + * This method is a hook method of the AbstractGlyphFactory. + * + * @return XHeadLocal + */ + public XHeadLocal createXHeadLocal() { + return (new XHeadLocal()); + } + + /** + * Creates a default XHead. + * This method is a hook method of the AbstractGlyphFactory. + * + * @return XHead + */ + public XHead createXHead() { + return (new XHead()); + } + + /** + * Creates a default XGlyphFile. + * This method is a hook method of the AbstractGlyphFactory. + * + * @return XGlyphFile + */ + public XGlyphFile createXGlyphFile() { + return (new XGlyphFile()); + } + + /** + * Creates a default XContour. + * This method is a hook method of the AbstractGlyphFactory. + * + * @return XContour + */ + public XContour createXContour() { + return (new XContour()); + } + + /** + * Creates a default XPoint2d. + * This method is a hook method of the AbstractGlyphFactory. + * + * @return XPoint2d + */ + public XPoint2d createXPoint2d() { + return (new XPoint2d()); + } + + /** + * Creates a default XInvokePos. + * This method is a hook method of the AbstractGlyphFactory. + * + * @return XInvokePos + */ + public XInvokePos createXInvokePos() { + return (new XInvokePos()); + } + + /** + * Creates a default XInvokeArg. + * This method is a hook method of the AbstractGlyphFactory. + * + * @return XInvokeArg + */ + public XInvokeArg createXInvokeArg() { + return (new XInvokeArg()); + } + + /** + * Creates a default XInvokeVarg. + * This method is a hook method of the AbstractGlyphFactory. + * + * @return XInvokeVarg + */ + public XInvokeVarg createXInvokeVarg() { + return (new XInvokeVarg()); + } + + /** + * Creates a default XInvoke. + * This method is a hook method of the AbstractGlyphFactory. + * + * @return XInvoke + */ + public XInvoke createXInvoke() { + return (new XInvoke()); + } + + /** + * Creates a default XInclude. + * This method is a hook method of the AbstractGlyphFactory. + * + * @return XInclude + */ + public XInclude createXInclude() { + return (new XInclude()); + } + + /** + * Creates a default XModule. + * This method is a hook method of the AbstractGlyphFactory. + * + * @return XModule + */ + public XModule createXModule() { + return (new XModule()); + } + + /** + * Creates a default XBody. + * This method is a hook method of the AbstractGlyphFactory. + * + * @return XBody + */ + public XBody createXBody() { + return (new XBody()); + } + + /** + * Creates a default XStartGlyphElement. + * This method is a hook method of the AbstractGlyphFactory. + * + * @return XStartGlyphElement + */ + public XStartGlyphElement createXStartGlyphElement() { + return (new XStartGlyphElement()); + } + + /** + * Creates a default XControlPoint. + * This method is a hook method of the AbstractGlyphFactory. + * + * @return XControlPoint + */ + public XControlPoint createXControlPoint() { + return (new XControlPoint()); + } + + /** + * Creates a default XHint. + * This method is a hook method of the AbstractGlyphFactory. + * + * @return XHint + */ + public XHint createXHint() { + return (new XHint()); + } + + /** + * Creates a default XContourPoint. + * This method is a hook method of the AbstractGlyphFactory. + * + * @return XContourPoint + */ + public XContourPoint createXContourPoint() { + return (new XContourPoint()); + } + + /** + * Creates a default XParamList. + * This method is a hook method of the AbstractGlyphFactory. + * + * @return XParamList + */ + public XParamList createXParamList() { + return (new XParamList()); + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/xml/GlyphFactory.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/xml/GlyphFactory.java new file mode 100644 index 000000000..b9c5ae8bf --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/xml/GlyphFactory.java @@ -0,0 +1,55 @@ +/* + * The Relaxer artifact + * Copyright (c) 2000-2004, ASAMI Tomoharu, All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package org.doubletype.ossa.xml; + +/** + * GlyphFactory is generated by Relaxer based on glyph.rng. + * + * @version glyph.rng 1.0 (Tue Nov 09 20:22:48 EST 2004) + * @author Relaxer 1.1b (http://www.relaxer.org) + */ +public class GlyphFactory { + private static IGlyphFactory factory; + + /** + * Sets a factory. + * + * @param newFactory + */ + public static void setFactory(IGlyphFactory newFactory) { + factory = newFactory; + } + + /** + * Gets the factory. + * + * @return IGlyphFactory + */ + public static IGlyphFactory getFactory() { + if (factory == null) { + factory = new DefaultGlyphFactory(); + } + return (factory); + } +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/xml/IGlyphFactory.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/xml/IGlyphFactory.java new file mode 100644 index 000000000..36547070c --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/xml/IGlyphFactory.java @@ -0,0 +1,2279 @@ +/* + * The Relaxer artifact + * Copyright (c) 2000-2004, ASAMI Tomoharu, All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package org.doubletype.ossa.xml; + +import java.io.*; +import java.net.URL; +import javax.xml.parsers.*; +import org.w3c.dom.*; +import org.xml.sax.*; + +/** + * IGlyphFactory is generated by Relaxer based on glyph.rng. + * + * @version glyph.rng 1.0 (Tue Nov 09 20:22:48 EST 2004) + * @author Relaxer 1.1b (http://www.relaxer.org) + */ +public interface IGlyphFactory { + /** + * Gets a Class of XParamListParam. + * + * @return Class + */ + Class getXParamListParamClass(); + + /** + * Gets a Class of XHeadGlobal. + * + * @return Class + */ + Class getXHeadGlobalClass(); + + /** + * Gets a Class of XHeadLocal. + * + * @return Class + */ + Class getXHeadLocalClass(); + + /** + * Gets a Class of XHead. + * + * @return Class + */ + Class getXHeadClass(); + + /** + * Gets a Class of XGlyphFile. + * + * @return Class + */ + Class getXGlyphFileClass(); + + /** + * Gets a Class of XContour. + * + * @return Class + */ + Class getXContourClass(); + + /** + * Gets a Class of XPoint2d. + * + * @return Class + */ + Class getXPoint2dClass(); + + /** + * Gets a Class of XInvokePos. + * + * @return Class + */ + Class getXInvokePosClass(); + + /** + * Gets a Class of XInvokeArg. + * + * @return Class + */ + Class getXInvokeArgClass(); + + /** + * Gets a Class of XInvokeVarg. + * + * @return Class + */ + Class getXInvokeVargClass(); + + /** + * Gets a Class of XInvoke. + * + * @return Class + */ + Class getXInvokeClass(); + + /** + * Gets a Class of XInclude. + * + * @return Class + */ + Class getXIncludeClass(); + + /** + * Gets a Class of XModule. + * + * @return Class + */ + Class getXModuleClass(); + + /** + * Gets a Class of XBody. + * + * @return Class + */ + Class getXBodyClass(); + + /** + * Gets a Class of XStartGlyphElement. + * + * @return Class + */ + Class getXStartGlyphElementClass(); + + /** + * Gets a Class of XControlPoint. + * + * @return Class + */ + Class getXControlPointClass(); + + /** + * Gets a Class of XHint. + * + * @return Class + */ + Class getXHintClass(); + + /** + * Gets a Class of XContourPoint. + * + * @return Class + */ + Class getXContourPointClass(); + + /** + * Gets a Class of XParamList. + * + * @return Class + */ + Class getXParamListClass(); + + /** + * Sets a errorHandler. + * + * @param errorHandler + */ + void setErrorHandler(org.xml.sax.ErrorHandler errorHandler); + + /** + * Gets a errorHandler. + * + * @return org.xml.sax.ErrorHandler + */ + org.xml.sax.ErrorHandler getErrorHandler(); + + /** + * Sets a entityResolver. + * + * @param entityResolver + */ + void setEntityResolver(org.xml.sax.EntityResolver entityResolver); + + /** + * Gets a entityResolver. + * + * @return org.xml.sax.EntityResolver + */ + org.xml.sax.EntityResolver getEntityResolver(); + + /** + * Sets a baseUri. + * + * @param baseUri + */ + void setBaseUri(String baseUri); + + /** + * Gets a baseUri. + * + * @return String + */ + String getBaseUri(); + + /** + * Creates a Object by the File file. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return Object + */ + Object create(File file) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a Object by the String representation of URI uri. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return Object + */ + Object create(String uri) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a Object by the URL url. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return Object + */ + Object create(URL url) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a Object by the InputStream in. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return Object + */ + Object create(InputStream in) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a Object by the InputSource is. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return Object + */ + Object create(InputSource is) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a Object by the Reader reader. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return Object + */ + Object create(Reader reader) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a Object by the Object source. + * + * @param source + * @return Object + */ + Object create(Object source); + + /** + * Creates a Object by the Document dom. + * + * @param doc + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return Object + */ + Object create(Document doc) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a Object by the Element element. + * + * @param element + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return Object + */ + Object create(Element element) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XParamListParam by the File file. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XParamListParam + */ + XParamListParam createXParamListParam(File file) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XHeadGlobal by the File file. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHeadGlobal + */ + XHeadGlobal createXHeadGlobal(File file) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XHeadLocal by the File file. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHeadLocal + */ + XHeadLocal createXHeadLocal(File file) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XHead by the File file. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHead + */ + XHead createXHead(File file) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XGlyphFile by the File file. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XGlyphFile + */ + XGlyphFile createXGlyphFile(File file) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XContour by the File file. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XContour + */ + XContour createXContour(File file) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XPoint2d by the File file. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XPoint2d + */ + XPoint2d createXPoint2d(File file) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XInvokePos by the File file. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokePos + */ + XInvokePos createXInvokePos(File file) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XInvokeArg by the File file. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokeArg + */ + XInvokeArg createXInvokeArg(File file) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XInvokeVarg by the File file. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokeVarg + */ + XInvokeVarg createXInvokeVarg(File file) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XInvoke by the File file. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvoke + */ + XInvoke createXInvoke(File file) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XInclude by the File file. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInclude + */ + XInclude createXInclude(File file) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XModule by the File file. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XModule + */ + XModule createXModule(File file) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XBody by the File file. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XBody + */ + XBody createXBody(File file) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XStartGlyphElement by the File file. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XStartGlyphElement + */ + XStartGlyphElement createXStartGlyphElement(File file) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XControlPoint by the File file. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XControlPoint + */ + XControlPoint createXControlPoint(File file) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XHint by the File file. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHint + */ + XHint createXHint(File file) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XContourPoint by the File file. + * + * @param file + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XContourPoint + */ + XContourPoint createXContourPoint(File file) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XParamListParam + * by the String representation of URI uri. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XParamListParam + */ + XParamListParam createXParamListParam(String uri) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XHeadGlobal + * by the String representation of URI uri. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHeadGlobal + */ + XHeadGlobal createXHeadGlobal(String uri) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XHeadLocal + * by the String representation of URI uri. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHeadLocal + */ + XHeadLocal createXHeadLocal(String uri) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XHead + * by the String representation of URI uri. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHead + */ + XHead createXHead(String uri) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XGlyphFile + * by the String representation of URI uri. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XGlyphFile + */ + XGlyphFile createXGlyphFile(String uri) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XContour + * by the String representation of URI uri. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XContour + */ + XContour createXContour(String uri) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XPoint2d + * by the String representation of URI uri. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XPoint2d + */ + XPoint2d createXPoint2d(String uri) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XInvokePos + * by the String representation of URI uri. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokePos + */ + XInvokePos createXInvokePos(String uri) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XInvokeArg + * by the String representation of URI uri. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokeArg + */ + XInvokeArg createXInvokeArg(String uri) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XInvokeVarg + * by the String representation of URI uri. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokeVarg + */ + XInvokeVarg createXInvokeVarg(String uri) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XInvoke + * by the String representation of URI uri. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvoke + */ + XInvoke createXInvoke(String uri) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XInclude + * by the String representation of URI uri. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInclude + */ + XInclude createXInclude(String uri) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XModule + * by the String representation of URI uri. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XModule + */ + XModule createXModule(String uri) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XBody + * by the String representation of URI uri. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XBody + */ + XBody createXBody(String uri) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XStartGlyphElement + * by the String representation of URI uri. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XStartGlyphElement + */ + XStartGlyphElement createXStartGlyphElement(String uri) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XControlPoint + * by the String representation of URI uri. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XControlPoint + */ + XControlPoint createXControlPoint(String uri) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XHint + * by the String representation of URI uri. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHint + */ + XHint createXHint(String uri) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XContourPoint + * by the String representation of URI uri. + * + * @param uri + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XContourPoint + */ + XContourPoint createXContourPoint(String uri) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XParamListParam by the URL url. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XParamListParam + */ + XParamListParam createXParamListParam(URL url) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XHeadGlobal by the URL url. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHeadGlobal + */ + XHeadGlobal createXHeadGlobal(URL url) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XHeadLocal by the URL url. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHeadLocal + */ + XHeadLocal createXHeadLocal(URL url) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XHead by the URL url. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHead + */ + XHead createXHead(URL url) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XGlyphFile by the URL url. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XGlyphFile + */ + XGlyphFile createXGlyphFile(URL url) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XContour by the URL url. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XContour + */ + XContour createXContour(URL url) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XPoint2d by the URL url. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XPoint2d + */ + XPoint2d createXPoint2d(URL url) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XInvokePos by the URL url. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokePos + */ + XInvokePos createXInvokePos(URL url) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XInvokeArg by the URL url. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokeArg + */ + XInvokeArg createXInvokeArg(URL url) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XInvokeVarg by the URL url. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokeVarg + */ + XInvokeVarg createXInvokeVarg(URL url) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XInvoke by the URL url. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvoke + */ + XInvoke createXInvoke(URL url) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XInclude by the URL url. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInclude + */ + XInclude createXInclude(URL url) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XModule by the URL url. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XModule + */ + XModule createXModule(URL url) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XBody by the URL url. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XBody + */ + XBody createXBody(URL url) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XStartGlyphElement by the URL url. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XStartGlyphElement + */ + XStartGlyphElement createXStartGlyphElement(URL url) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XControlPoint by the URL url. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XControlPoint + */ + XControlPoint createXControlPoint(URL url) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XHint by the URL url. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHint + */ + XHint createXHint(URL url) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XContourPoint by the URL url. + * + * @param url + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XContourPoint + */ + XContourPoint createXContourPoint(URL url) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XParamListParam by the InputStream in. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XParamListParam + */ + XParamListParam createXParamListParam(InputStream in) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XHeadGlobal by the InputStream in. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHeadGlobal + */ + XHeadGlobal createXHeadGlobal(InputStream in) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XHeadLocal by the InputStream in. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHeadLocal + */ + XHeadLocal createXHeadLocal(InputStream in) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XHead by the InputStream in. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHead + */ + XHead createXHead(InputStream in) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XGlyphFile by the InputStream in. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XGlyphFile + */ + XGlyphFile createXGlyphFile(InputStream in) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XContour by the InputStream in. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XContour + */ + XContour createXContour(InputStream in) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XPoint2d by the InputStream in. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XPoint2d + */ + XPoint2d createXPoint2d(InputStream in) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XInvokePos by the InputStream in. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokePos + */ + XInvokePos createXInvokePos(InputStream in) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XInvokeArg by the InputStream in. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokeArg + */ + XInvokeArg createXInvokeArg(InputStream in) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XInvokeVarg by the InputStream in. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokeVarg + */ + XInvokeVarg createXInvokeVarg(InputStream in) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XInvoke by the InputStream in. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvoke + */ + XInvoke createXInvoke(InputStream in) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XInclude by the InputStream in. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInclude + */ + XInclude createXInclude(InputStream in) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XModule by the InputStream in. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XModule + */ + XModule createXModule(InputStream in) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XBody by the InputStream in. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XBody + */ + XBody createXBody(InputStream in) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XStartGlyphElement by the InputStream in. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XStartGlyphElement + */ + XStartGlyphElement createXStartGlyphElement(InputStream in) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XControlPoint by the InputStream in. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XControlPoint + */ + XControlPoint createXControlPoint(InputStream in) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XHint by the InputStream in. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHint + */ + XHint createXHint(InputStream in) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XContourPoint by the InputStream in. + * + * @param in + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XContourPoint + */ + XContourPoint createXContourPoint(InputStream in) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XParamListParam by the InputSource is. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XParamListParam + */ + XParamListParam createXParamListParam(InputSource is) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XHeadGlobal by the InputSource is. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHeadGlobal + */ + XHeadGlobal createXHeadGlobal(InputSource is) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XHeadLocal by the InputSource is. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHeadLocal + */ + XHeadLocal createXHeadLocal(InputSource is) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XHead by the InputSource is. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHead + */ + XHead createXHead(InputSource is) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XGlyphFile by the InputSource is. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XGlyphFile + */ + XGlyphFile createXGlyphFile(InputSource is) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XContour by the InputSource is. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XContour + */ + XContour createXContour(InputSource is) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XPoint2d by the InputSource is. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XPoint2d + */ + XPoint2d createXPoint2d(InputSource is) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XInvokePos by the InputSource is. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokePos + */ + XInvokePos createXInvokePos(InputSource is) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XInvokeArg by the InputSource is. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokeArg + */ + XInvokeArg createXInvokeArg(InputSource is) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XInvokeVarg by the InputSource is. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokeVarg + */ + XInvokeVarg createXInvokeVarg(InputSource is) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XInvoke by the InputSource is. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvoke + */ + XInvoke createXInvoke(InputSource is) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XInclude by the InputSource is. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInclude + */ + XInclude createXInclude(InputSource is) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XModule by the InputSource is. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XModule + */ + XModule createXModule(InputSource is) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XBody by the InputSource is. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XBody + */ + XBody createXBody(InputSource is) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XStartGlyphElement by the InputSource is. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XStartGlyphElement + */ + XStartGlyphElement createXStartGlyphElement(InputSource is) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XControlPoint by the InputSource is. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XControlPoint + */ + XControlPoint createXControlPoint(InputSource is) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XHint by the InputSource is. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHint + */ + XHint createXHint(InputSource is) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XContourPoint by the InputSource is. + * + * @param is + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XContourPoint + */ + XContourPoint createXContourPoint(InputSource is) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XParamListParam by the Reader reader. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XParamListParam + */ + XParamListParam createXParamListParam(Reader reader) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XHeadGlobal by the Reader reader. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHeadGlobal + */ + XHeadGlobal createXHeadGlobal(Reader reader) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XHeadLocal by the Reader reader. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHeadLocal + */ + XHeadLocal createXHeadLocal(Reader reader) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XHead by the Reader reader. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHead + */ + XHead createXHead(Reader reader) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XGlyphFile by the Reader reader. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XGlyphFile + */ + XGlyphFile createXGlyphFile(Reader reader) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XContour by the Reader reader. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XContour + */ + XContour createXContour(Reader reader) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XPoint2d by the Reader reader. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XPoint2d + */ + XPoint2d createXPoint2d(Reader reader) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XInvokePos by the Reader reader. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokePos + */ + XInvokePos createXInvokePos(Reader reader) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XInvokeArg by the Reader reader. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokeArg + */ + XInvokeArg createXInvokeArg(Reader reader) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XInvokeVarg by the Reader reader. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvokeVarg + */ + XInvokeVarg createXInvokeVarg(Reader reader) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XInvoke by the Reader reader. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInvoke + */ + XInvoke createXInvoke(Reader reader) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XInclude by the Reader reader. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XInclude + */ + XInclude createXInclude(Reader reader) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XModule by the Reader reader. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XModule + */ + XModule createXModule(Reader reader) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XBody by the Reader reader. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XBody + */ + XBody createXBody(Reader reader) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XStartGlyphElement by the Reader reader. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XStartGlyphElement + */ + XStartGlyphElement createXStartGlyphElement(Reader reader) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XControlPoint by the Reader reader. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XControlPoint + */ + XControlPoint createXControlPoint(Reader reader) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XHint by the Reader reader. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XHint + */ + XHint createXHint(Reader reader) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XContourPoint by the Reader reader. + * + * @param reader + * @exception IOException + * @exception SAXException + * @exception ParserConfigurationException + * @return XContourPoint + */ + XContourPoint createXContourPoint(Reader reader) throws IOException, SAXException, ParserConfigurationException; + + /** + * Creates a XParamListParam. + * + * @return XParamListParam + */ + XParamListParam createXParamListParam(); + + /** + * Creates a XHeadGlobal. + * + * @return XHeadGlobal + */ + XHeadGlobal createXHeadGlobal(); + + /** + * Creates a XHeadLocal. + * + * @return XHeadLocal + */ + XHeadLocal createXHeadLocal(); + + /** + * Creates a XHead. + * + * @return XHead + */ + XHead createXHead(); + + /** + * Creates a XGlyphFile. + * + * @return XGlyphFile + */ + XGlyphFile createXGlyphFile(); + + /** + * Creates a XContour. + * + * @return XContour + */ + XContour createXContour(); + + /** + * Creates a XPoint2d. + * + * @return XPoint2d + */ + XPoint2d createXPoint2d(); + + /** + * Creates a XInvokePos. + * + * @return XInvokePos + */ + XInvokePos createXInvokePos(); + + /** + * Creates a XInvokeArg. + * + * @return XInvokeArg + */ + XInvokeArg createXInvokeArg(); + + /** + * Creates a XInvokeVarg. + * + * @return XInvokeVarg + */ + XInvokeVarg createXInvokeVarg(); + + /** + * Creates a XInvoke. + * + * @return XInvoke + */ + XInvoke createXInvoke(); + + /** + * Creates a XInclude. + * + * @return XInclude + */ + XInclude createXInclude(); + + /** + * Creates a XModule. + * + * @return XModule + */ + XModule createXModule(); + + /** + * Creates a XBody. + * + * @return XBody + */ + XBody createXBody(); + + /** + * Creates a XStartGlyphElement. + * + * @return XStartGlyphElement + */ + XStartGlyphElement createXStartGlyphElement(); + + /** + * Creates a XControlPoint. + * + * @return XControlPoint + */ + XControlPoint createXControlPoint(); + + /** + * Creates a XHint. + * + * @return XHint + */ + XHint createXHint(); + + /** + * Creates a XContourPoint. + * + * @return XContourPoint + */ + XContourPoint createXContourPoint(); + + /** + * Creates a XParamListParam by the XParamListParam source. + * + * @param source + * @return XParamListParam + */ + XParamListParam createXParamListParam(XParamListParam source); + + /** + * Creates a XHeadGlobal by the XHeadGlobal source. + * + * @param source + * @return XHeadGlobal + */ + XHeadGlobal createXHeadGlobal(XHeadGlobal source); + + /** + * Creates a XHeadLocal by the XHeadLocal source. + * + * @param source + * @return XHeadLocal + */ + XHeadLocal createXHeadLocal(XHeadLocal source); + + /** + * Creates a XHead by the XHead source. + * + * @param source + * @return XHead + */ + XHead createXHead(XHead source); + + /** + * Creates a XGlyphFile by the XGlyphFile source. + * + * @param source + * @return XGlyphFile + */ + XGlyphFile createXGlyphFile(XGlyphFile source); + + /** + * Creates a XContour by the XContour source. + * + * @param source + * @return XContour + */ + XContour createXContour(XContour source); + + /** + * Creates a XPoint2d by the XPoint2d source. + * + * @param source + * @return XPoint2d + */ + XPoint2d createXPoint2d(XPoint2d source); + + /** + * Creates a XInvokePos by the XInvokePos source. + * + * @param source + * @return XInvokePos + */ + XInvokePos createXInvokePos(XInvokePos source); + + /** + * Creates a XInvokeArg by the XInvokeArg source. + * + * @param source + * @return XInvokeArg + */ + XInvokeArg createXInvokeArg(XInvokeArg source); + + /** + * Creates a XInvokeVarg by the XInvokeVarg source. + * + * @param source + * @return XInvokeVarg + */ + XInvokeVarg createXInvokeVarg(XInvokeVarg source); + + /** + * Creates a XInvoke by the XInvoke source. + * + * @param source + * @return XInvoke + */ + XInvoke createXInvoke(XInvoke source); + + /** + * Creates a XInclude by the XInclude source. + * + * @param source + * @return XInclude + */ + XInclude createXInclude(XInclude source); + + /** + * Creates a XModule by the XModule source. + * + * @param source + * @return XModule + */ + XModule createXModule(XModule source); + + /** + * Creates a XBody by the XBody source. + * + * @param source + * @return XBody + */ + XBody createXBody(XBody source); + + /** + * Creates a XStartGlyphElement by the XStartGlyphElement source. + * + * @param source + * @return XStartGlyphElement + */ + XStartGlyphElement createXStartGlyphElement(XStartGlyphElement source); + + /** + * Creates a XControlPoint by the XControlPoint source. + * + * @param source + * @return XControlPoint + */ + XControlPoint createXControlPoint(XControlPoint source); + + /** + * Creates a XHint by the XHint source. + * + * @param source + * @return XHint + */ + XHint createXHint(XHint source); + + /** + * Creates a XContourPoint by the XContourPoint source. + * + * @param source + * @return XContourPoint + */ + XContourPoint createXContourPoint(XContourPoint source); + + /** + * Creates a XParamListParam by the Document doc. + * + * @param doc + * @return XParamListParam + */ + XParamListParam createXParamListParam(Document doc); + + /** + * Creates a XHeadGlobal by the Document doc. + * + * @param doc + * @return XHeadGlobal + */ + XHeadGlobal createXHeadGlobal(Document doc); + + /** + * Creates a XHeadLocal by the Document doc. + * + * @param doc + * @return XHeadLocal + */ + XHeadLocal createXHeadLocal(Document doc); + + /** + * Creates a XHead by the Document doc. + * + * @param doc + * @return XHead + */ + XHead createXHead(Document doc); + + /** + * Creates a XGlyphFile by the Document doc. + * + * @param doc + * @return XGlyphFile + */ + XGlyphFile createXGlyphFile(Document doc); + + /** + * Creates a XContour by the Document doc. + * + * @param doc + * @return XContour + */ + XContour createXContour(Document doc); + + /** + * Creates a XPoint2d by the Document doc. + * + * @param doc + * @return XPoint2d + */ + XPoint2d createXPoint2d(Document doc); + + /** + * Creates a XInvokePos by the Document doc. + * + * @param doc + * @return XInvokePos + */ + XInvokePos createXInvokePos(Document doc); + + /** + * Creates a XInvokeArg by the Document doc. + * + * @param doc + * @return XInvokeArg + */ + XInvokeArg createXInvokeArg(Document doc); + + /** + * Creates a XInvokeVarg by the Document doc. + * + * @param doc + * @return XInvokeVarg + */ + XInvokeVarg createXInvokeVarg(Document doc); + + /** + * Creates a XInvoke by the Document doc. + * + * @param doc + * @return XInvoke + */ + XInvoke createXInvoke(Document doc); + + /** + * Creates a XInclude by the Document doc. + * + * @param doc + * @return XInclude + */ + XInclude createXInclude(Document doc); + + /** + * Creates a XModule by the Document doc. + * + * @param doc + * @return XModule + */ + XModule createXModule(Document doc); + + /** + * Creates a XBody by the Document doc. + * + * @param doc + * @return XBody + */ + XBody createXBody(Document doc); + + /** + * Creates a XStartGlyphElement by the Document doc. + * + * @param doc + * @return XStartGlyphElement + */ + XStartGlyphElement createXStartGlyphElement(Document doc); + + /** + * Creates a XControlPoint by the Document doc. + * + * @param doc + * @return XControlPoint + */ + XControlPoint createXControlPoint(Document doc); + + /** + * Creates a XHint by the Document doc. + * + * @param doc + * @return XHint + */ + XHint createXHint(Document doc); + + /** + * Creates a XContourPoint by the Document doc. + * + * @param doc + * @return XContourPoint + */ + XContourPoint createXContourPoint(Document doc); + + /** + * Creates a XParamListParam by the Element element. + * + * @param element + * @return XParamListParam + */ + XParamListParam createXParamListParam(Element element); + + /** + * Creates a XHeadGlobal by the Element element. + * + * @param element + * @return XHeadGlobal + */ + XHeadGlobal createXHeadGlobal(Element element); + + /** + * Creates a XHeadLocal by the Element element. + * + * @param element + * @return XHeadLocal + */ + XHeadLocal createXHeadLocal(Element element); + + /** + * Creates a XHead by the Element element. + * + * @param element + * @return XHead + */ + XHead createXHead(Element element); + + /** + * Creates a XGlyphFile by the Element element. + * + * @param element + * @return XGlyphFile + */ + XGlyphFile createXGlyphFile(Element element); + + /** + * Creates a XContour by the Element element. + * + * @param element + * @return XContour + */ + XContour createXContour(Element element); + + /** + * Creates a XPoint2d by the Element element. + * + * @param element + * @return XPoint2d + */ + XPoint2d createXPoint2d(Element element); + + /** + * Creates a XInvokePos by the Element element. + * + * @param element + * @return XInvokePos + */ + XInvokePos createXInvokePos(Element element); + + /** + * Creates a XInvokeArg by the Element element. + * + * @param element + * @return XInvokeArg + */ + XInvokeArg createXInvokeArg(Element element); + + /** + * Creates a XInvokeVarg by the Element element. + * + * @param element + * @return XInvokeVarg + */ + XInvokeVarg createXInvokeVarg(Element element); + + /** + * Creates a XInvoke by the Element element. + * + * @param element + * @return XInvoke + */ + XInvoke createXInvoke(Element element); + + /** + * Creates a XInclude by the Element element. + * + * @param element + * @return XInclude + */ + XInclude createXInclude(Element element); + + /** + * Creates a XModule by the Element element. + * + * @param element + * @return XModule + */ + XModule createXModule(Element element); + + /** + * Creates a XBody by the Element element. + * + * @param element + * @return XBody + */ + XBody createXBody(Element element); + + /** + * Creates a XStartGlyphElement by the Element element. + * + * @param element + * @return XStartGlyphElement + */ + XStartGlyphElement createXStartGlyphElement(Element element); + + /** + * Creates a XControlPoint by the Element element. + * + * @param element + * @return XControlPoint + */ + XControlPoint createXControlPoint(Element element); + + /** + * Creates a XHint by the Element element. + * + * @param element + * @return XHint + */ + XHint createXHint(Element element); + + /** + * Creates a XContourPoint by the Element element. + * + * @param element + * @return XContourPoint + */ + XContourPoint createXContourPoint(Element element); + + /** + * Creates a XParamListParam by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * + * @param stack + * @return XParamListParam + */ + XParamListParam createXParamListParam(RStack stack); + + /** + * Creates a XHeadGlobal by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * + * @param stack + * @return XHeadGlobal + */ + XHeadGlobal createXHeadGlobal(RStack stack); + + /** + * Creates a XHeadLocal by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * + * @param stack + * @return XHeadLocal + */ + XHeadLocal createXHeadLocal(RStack stack); + + /** + * Creates a XHead by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * + * @param stack + * @return XHead + */ + XHead createXHead(RStack stack); + + /** + * Creates a XGlyphFile by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * + * @param stack + * @return XGlyphFile + */ + XGlyphFile createXGlyphFile(RStack stack); + + /** + * Creates a XContour by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * + * @param stack + * @return XContour + */ + XContour createXContour(RStack stack); + + /** + * Creates a XPoint2d by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * + * @param stack + * @return XPoint2d + */ + XPoint2d createXPoint2d(RStack stack); + + /** + * Creates a XInvokePos by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * + * @param stack + * @return XInvokePos + */ + XInvokePos createXInvokePos(RStack stack); + + /** + * Creates a XInvokeArg by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * + * @param stack + * @return XInvokeArg + */ + XInvokeArg createXInvokeArg(RStack stack); + + /** + * Creates a XInvokeVarg by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * + * @param stack + * @return XInvokeVarg + */ + XInvokeVarg createXInvokeVarg(RStack stack); + + /** + * Creates a XInvoke by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * + * @param stack + * @return XInvoke + */ + XInvoke createXInvoke(RStack stack); + + /** + * Creates a XInclude by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * + * @param stack + * @return XInclude + */ + XInclude createXInclude(RStack stack); + + /** + * Creates a XModule by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * + * @param stack + * @return XModule + */ + XModule createXModule(RStack stack); + + /** + * Creates a XBody by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * + * @param stack + * @return XBody + */ + XBody createXBody(RStack stack); + + /** + * Creates a XStartGlyphElement by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * + * @param stack + * @return XStartGlyphElement + */ + XStartGlyphElement createXStartGlyphElement(RStack stack); + + /** + * Creates a XControlPoint by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * + * @param stack + * @return XControlPoint + */ + XControlPoint createXControlPoint(RStack stack); + + /** + * Creates a XHint by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * + * @param stack + * @return XHint + */ + XHint createXHint(RStack stack); + + /** + * Creates a XContourPoint by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * + * @param stack + * @return XContourPoint + */ + XContourPoint createXContourPoint(RStack stack); + + /** + * Creates a XParamList by the Element element. + * + * @return XParamList + */ + XParamList createXParamList(); + + /** + * Creates a XParamList by the Stack stack. + * This mehtod is supposed to be used internally + * by the Relaxer system. + * + * @param stack + * @return XParamList + */ + XParamList createXParamList(RStack stack); + + /** + * Creates a XParamList by the object source. + * This method is a template method for concrete classes. + * + * @param source + * @return XParamList + */ + XParamList createXParamList(XParamList source); +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/xml/IRNode.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/xml/IRNode.java new file mode 100644 index 000000000..2e513627e --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/xml/IRNode.java @@ -0,0 +1,51 @@ +/* + * The Relaxer artifact + * Copyright (c) 2000-2004, ASAMI Tomoharu, All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package org.doubletype.ossa.xml; + +/** + * @version glyph.rng 1.0 (Tue Nov 09 20:22:48 EST 2004) + * @author Relaxer 1.1b (http://www.relaxer.org) + */ +public interface IRNode { + /** + * Sets parent RNode. + * + * @param parent + */ + void rSetParentRNode(IRNode parent); + + /** + * Gets parent RNode. + * + * @return IRNode + */ + IRNode rGetParentRNode(); + + /** + * Gets child RNodes. + * + * @return IRNode[] + */ + IRNode[] rGetRNodes(); +} diff --git a/trunk/libsrc/ttf/src/org/doubletype/ossa/xml/RInterleave.java b/trunk/libsrc/ttf/src/org/doubletype/ossa/xml/RInterleave.java new file mode 100644 index 000000000..5abbc2c00 --- /dev/null +++ b/trunk/libsrc/ttf/src/org/doubletype/ossa/xml/RInterleave.java @@ -0,0 +1,757 @@ +/* + * The Relaxer artifact + * Copyright (c) 2000-2004, ASAMI Tomoharu, All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package org.doubletype.ossa.xml; + +import java.util.*; +import java.net.URL; +import java.math.*; +import java.lang.reflect.*; +import java.sql.Time; +import java.sql.Timestamp; +import org.w3c.dom.*; + +/** + * RInterleave + * + * @since May. 13, 2002 + * @version Oct. 22, 2003 + * @author ASAMI, Tomoharu (asami@relaxer.org) + */ +@SuppressWarnings("all") +public final class RInterleave { + private RStack rstack_; + private List entries_ = new ArrayList<>(); + private Map entryByStateClass_ = new HashMap<>(); + private Map entryByElementName_ = new HashMap<>(); + private Boolean isMatch_ = null; + + public RInterleave(RStack rstack) { + rstack_ = rstack; + } + + public Object getProperty(Class stateClass) { + StateClassEntry entry = _getEntryByStateClass(stateClass); + return (entry.getObject()); + } + + public Object[] getPropertyList(Class stateClass) { + StateClassEntry entry = _getEntryByStateClass(stateClass); + return (entry.getObjects()); + } + + public String getElementPropertyAsString(String elementName) { + Element element = _getElementByElementName(elementName); + if (element == null) { + return (null); + } + return (URelaxer.getElementPropertyAsString(element)); + } + + public boolean getElementPropertyAsBoolean(String elementName) { + Element element = _getElementByElementName(elementName); + if (element == null) { + return (false); + } + return (URelaxer.getElementPropertyAsBoolean(element)); + } + + public Boolean getElementPropertyAsBooleanObject(String elementName) { + Element element = _getElementByElementName(elementName); + if (element == null) { + return (null); + } + return (URelaxer.getElementPropertyAsBooleanObject(element)); + } + + public byte getElementPropertyAsByte(String elementName) { + Element element = _getElementByElementName(elementName); + if (element == null) { + return (-1); + } + return (URelaxer.getElementPropertyAsByte(element)); + } + + public Byte getElementPropertyAsByteObject(String elementName) { + Element element = _getElementByElementName(elementName); + if (element == null) { + return (null); + } + return (URelaxer.getElementPropertyAsByteObject(element)); + } + + public short getElementPropertyAsShort(String elementName) { + Element element = _getElementByElementName(elementName); + if (element == null) { + return (-1); + } + return (URelaxer.getElementPropertyAsShort(element)); + } + + public Short getElementPropertyAsShortObject(String elementName) { + Element element = _getElementByElementName(elementName); + if (element == null) { + return (null); + } + return (URelaxer.getElementPropertyAsShortObject(element)); + } + + public int getElementPropertyAsInt(String elementName) { + Element element = _getElementByElementName(elementName); + if (element == null) { + return (-1); + } + return (URelaxer.getElementPropertyAsInt(element)); + } + + public Integer getElementPropertyAsIntObject(String elementName) { + Element element = _getElementByElementName(elementName); + if (element == null) { + return (null); + } + return (URelaxer.getElementPropertyAsIntObject(element)); + } + + public long getElementPropertyAsLong(String elementName) { + Element element = _getElementByElementName(elementName); + if (element == null) { + return (-1); + } + return (URelaxer.getElementPropertyAsLong(element)); + } + + public Long getElementPropertyAsLongObject(String elementName) { + Element element = _getElementByElementName(elementName); + if (element == null) { + return (null); + } + return (URelaxer.getElementPropertyAsLongObject(element)); + } + + public float getElementPropertyAsFloat(String elementName) { + Element element = _getElementByElementName(elementName); + if (element == null) { + return (Float.NaN); + } + return (URelaxer.getElementPropertyAsFloat(element)); + } + + public Float getElementPropertyAsFloatObject(String elementName) { + Element element = _getElementByElementName(elementName); + if (element == null) { + return (null); + } + return (URelaxer.getElementPropertyAsFloatObject(element)); + } + + public double getElementPropertyAsDouble(String elementName) { + Element element = _getElementByElementName(elementName); + if (element == null) { + return (Double.NaN); + } + return (URelaxer.getElementPropertyAsDouble(element)); + } + + public Double getElementPropertyAsDoubleObject(String elementName) { + Element element = _getElementByElementName(elementName); + if (element == null) { + return (null); + } + return (URelaxer.getElementPropertyAsDoubleObject(element)); + } + + public BigDecimal getElementPropertyAsBigDecimal(String elementName) { + Element element = _getElementByElementName(elementName); + if (element == null) { + return (null); + } + return (URelaxer.getElementPropertyAsBigDecimal(element)); + } + + public BigInteger getElementPropertyAsBigInteger(String elementName) { + Element element = _getElementByElementName(elementName); + if (element == null) { + return (null); + } + return (URelaxer.getElementPropertyAsBigInteger(element)); + } + + public Date getElementPropertyAsDate(String elementName) { + Element element = _getElementByElementName(elementName); + if (element == null) { + return (null); + } + return (URelaxer.getElementPropertyAsDate(element)); + } + + public Locale getElementPropertyAsLocale(String elementName) { + Element element = _getElementByElementName(elementName); + if (element == null) { + return (null); + } + return (URelaxer.getElementPropertyAsLocale(element)); + } + + public URL getElementPropertyAsURL(String elementName) { + Element element = _getElementByElementName(elementName); + if (element == null) { + return (null); + } + return (URelaxer.getElementPropertyAsURL(element)); + } + + public java.sql.Timestamp getElementPropertyAsSQLTimestamp( + String elementName + ) { + Element element = _getElementByElementName(elementName); + if (element == null) { + return (null); + } + return (URelaxer.getElementPropertyAsSQLTimestamp(element)); + } + + public java.sql.Time getElementPropertyAsSQLTime( + String elementName + ) { + Element element = _getElementByElementName(elementName); + if (element == null) { + return (null); + } + return (URelaxer.getElementPropertyAsSQLTime(element)); + } + + public java.sql.Date getElementPropertyAsSQLDate( + String elementName + ) { + Element element = _getElementByElementName(elementName); + if (element == null) { + return (null); + } + return (URelaxer.getElementPropertyAsSQLDate(element)); + } + + public byte[] getElementPropertyAsBinaryBASE64( + String elementName + ) { + Element element = _getElementByElementName(elementName); + if (element == null) { + return (null); + } + return (URelaxer.getElementPropertyAsBinaryBASE64(element)); + } + + public byte[] getElementPropertyAsBinaryHEX( + String elementName + ) { + Element element = _getElementByElementName(elementName); + if (element == null) { + return (null); + } + return (URelaxer.getElementPropertyAsBinaryHEX(element)); + } + + public List getElementPropertyAsStringList(String elementName) { + List list = _getElementListByElementName(elementName); + int size = list.size(); + List result = new ArrayList<>(); + for (int i = 0;i < size;i++) { + Element element = (Element)list.get(i); + result.add(URelaxer.getElementPropertyAsString(element)); + } + return (result); + } + + public List getElementPropertyAsBooleanList(String elementName) { + List list = _getElementListByElementName(elementName); + int size = list.size(); + List result = new ArrayList<>(); + for (int i = 0;i < size;i++) { + Element element = (Element)list.get(i); + result.add(URelaxer.getElementPropertyAsBooleanObject(element)); + } + return (result); + } + + public List getElementPropertyAsByteList(String elementName) { + List list = _getElementListByElementName(elementName); + int size = list.size(); + List result = new ArrayList<>(); + for (int i = 0;i < size;i++) { + Element element = (Element)list.get(i); + result.add(URelaxer.getElementPropertyAsByteObject(element)); + } + return (result); + } + + public List getElementPropertyAsShortList(String elementName) { + List list = _getElementListByElementName(elementName); + int size = list.size(); + List result = new ArrayList<>(); + for (int i = 0;i < size;i++) { + Element element = (Element)list.get(i); + result.add(URelaxer.getElementPropertyAsShortObject(element)); + } + return (result); + } + + public List getElementPropertyAsIntList(String elementName) { + List list = _getElementListByElementName(elementName); + int size = list.size(); + List result = new ArrayList<>(); + for (int i = 0;i < size;i++) { + Element element = (Element)list.get(i); + result.add(URelaxer.getElementPropertyAsIntObject(element)); + } + return (result); + } + + public List getElementPropertyAsLongList(String elementName) { + List list = _getElementListByElementName(elementName); + int size = list.size(); + List result = new ArrayList<>(); + for (int i = 0;i < size;i++) { + Element element = (Element)list.get(i); + result.add(URelaxer.getElementPropertyAsLongObject(element)); + } + return (result); + } + + public List getElementPropertyAsFloatList(String elementName) { + List list = _getElementListByElementName(elementName); + int size = list.size(); + List result = new ArrayList<>(); + for (int i = 0;i < size;i++) { + Element element = (Element)list.get(i); + result.add(URelaxer.getElementPropertyAsFloatObject(element)); + } + return (result); + } + + public List getElementPropertyAsDoubleList(String elementName) { + List list = _getElementListByElementName(elementName); + int size = list.size(); + List result = new ArrayList<>(); + for (int i = 0;i < size;i++) { + Element element = (Element)list.get(i); + result.add(URelaxer.getElementPropertyAsDoubleObject(element)); + } + return (result); + } + + public List getElementPropertyAsBigDecimalList(String elementName) { + List list = _getElementListByElementName(elementName); + int size = list.size(); + List result = new ArrayList<>(); + for (int i = 0;i < size;i++) { + Element element = (Element)list.get(i); + result.add(URelaxer.getElementPropertyAsBigDecimal(element)); + } + return (result); + } + + public List getElementPropertyAsBigIntegerList(String elementName) { + List list = _getElementListByElementName(elementName); + int size = list.size(); + List result = new ArrayList<>(); + for (int i = 0;i < size;i++) { + Element element = (Element)list.get(i); + result.add(URelaxer.getElementPropertyAsBigInteger(element)); + } + return (result); + } + + public List getElementPropertyAsDateList(String elementName) { + List list = _getElementListByElementName(elementName); + int size = list.size(); + List result = new ArrayList<>(); + for (int i = 0;i < size;i++) { + Element element = (Element)list.get(i); + result.add(URelaxer.getElementPropertyAsDate(element)); + } + return (result); + } + + public List getElementPropertyAsLocaleList(String elementName) { + List list = _getElementListByElementName(elementName); + int size = list.size(); + List result = new ArrayList<>(); + for (int i = 0;i < size;i++) { + Element element = (Element)list.get(i); + result.add(URelaxer.getElementPropertyAsLocale(element)); + } + return (result); + } + + public List getElementPropertyAsURLList(String elementName) { + List list = _getElementListByElementName(elementName); + int size = list.size(); + List result = new ArrayList<>(); + for (int i = 0;i < size;i++) { + Element element = (Element)list.get(i); + result.add(URelaxer.getElementPropertyAsURL(element)); + } + return (result); + } + + public List getElementPropertyAsSQLTimestampList( + String elementName + ) { + List list = _getElementListByElementName(elementName); + int size = list.size(); + List result = new ArrayList<>(); + for (int i = 0;i < size;i++) { + Element element = (Element)list.get(i); + result.add(URelaxer.getElementPropertyAsSQLTimestamp(element)); + } + return (result); + } + + public List