(empty log message)
@@ -69,16 +69,20 @@ | ||
69 | 69 | <plugin> |
70 | 70 | <groupId>org.codehaus.mojo</groupId> |
71 | 71 | <artifactId>native2ascii-maven-plugin</artifactId> |
72 | + <version>2.0.1</version> | |
72 | 73 | <executions> |
73 | 74 | <execution> |
75 | + <id>native2ascii-utf8-properties</id> | |
76 | + <phase>process-resources</phase> | |
74 | 77 | <goals> |
75 | - <goal>resources</goal> | |
78 | + <goal>inplace</goal> | |
76 | 79 | </goals> |
77 | - | |
78 | 80 | <configuration> |
81 | + <dir>${project.build.directory}/classes</dir> | |
82 | + <includes> | |
83 | + <include>**/*.properties</include> | |
84 | + </includes> | |
79 | 85 | <encoding>UTF-8</encoding> |
80 | - <src>src/main/resources</src> | |
81 | - <dest>target/resources</dest> | |
82 | 86 | </configuration> |
83 | 87 | </execution> |
84 | 88 | </executions> |
@@ -59,16 +59,20 @@ | ||
59 | 59 | <plugin> |
60 | 60 | <groupId>org.codehaus.mojo</groupId> |
61 | 61 | <artifactId>native2ascii-maven-plugin</artifactId> |
62 | + <version>2.0.1</version> | |
62 | 63 | <executions> |
63 | 64 | <execution> |
65 | + <id>native2ascii-utf8-properties</id> | |
66 | + <phase>process-resources</phase> | |
64 | 67 | <goals> |
65 | - <goal>resources</goal> | |
68 | + <goal>inplace</goal> | |
66 | 69 | </goals> |
67 | - | |
68 | 70 | <configuration> |
71 | + <dir>${project.build.directory}/classes</dir> | |
72 | + <includes> | |
73 | + <include>**/*.properties</include> | |
74 | + </includes> | |
69 | 75 | <encoding>UTF-8</encoding> |
70 | - <src>src/main/resources</src> | |
71 | - <dest>target/resources</dest> | |
72 | 76 | </configuration> |
73 | 77 | </execution> |
74 | 78 | </executions> |
@@ -9,7 +9,7 @@ | ||
9 | 9 | <groupId>net.zamasoft</groupId> |
10 | 10 | <artifactId>homare</artifactId> |
11 | 11 | <packaging>jar</packaging> |
12 | - <version>3.2.15</version> | |
12 | + <version>3.2.16</version> | |
13 | 13 | <name>Homare</name> |
14 | 14 | <description>印刷向けのHTML/CSSレンダリングエンジンです。</description> |
15 | 15 | <url>https://copper.osdn.jp/homare/</url> |
@@ -18,7 +18,7 @@ | ||
18 | 18 | <dependency> |
19 | 19 | <groupId>net.zamasoft</groupId> |
20 | 20 | <artifactId>sakae-pdf</artifactId> |
21 | - <version>0.9.9</version> | |
21 | + <version>1.0.0</version> | |
22 | 22 | </dependency> |
23 | 23 | <dependency> |
24 | 24 | <groupId>net.zamasoft</groupId> |
@@ -149,16 +149,20 @@ | ||
149 | 149 | <plugin> |
150 | 150 | <groupId>org.codehaus.mojo</groupId> |
151 | 151 | <artifactId>native2ascii-maven-plugin</artifactId> |
152 | + <version>2.0.1</version> | |
152 | 153 | <executions> |
153 | 154 | <execution> |
155 | + <id>native2ascii-utf8-properties</id> | |
156 | + <phase>process-resources</phase> | |
154 | 157 | <goals> |
155 | - <goal>resources</goal> | |
158 | + <goal>inplace</goal> | |
156 | 159 | </goals> |
157 | - | |
158 | 160 | <configuration> |
161 | + <dir>${project.build.directory}/classes</dir> | |
162 | + <includes> | |
163 | + <include>**/*.properties</include> | |
164 | + </includes> | |
159 | 165 | <encoding>UTF-8</encoding> |
160 | - <src>src/main/resources</src> | |
161 | - <dest>target/resources</dest> | |
162 | 166 | </configuration> |
163 | 167 | </execution> |
164 | 168 | </executions> |
@@ -43,6 +43,7 @@ | ||
43 | 43 | public static final short WARN_UNSUPPORTED_ENCODING = 0x281D; |
44 | 44 | public static final short WARN_MISSING_FONT_FILE = 0x281E; |
45 | 45 | public static final short WARN_MISSING_FONT = 0x281F; |
46 | + public static final short WARN_MISSING_FONT_OUTLINE = 0x2820; | |
46 | 47 | public static final short WARN_PLUGIN = 0x28FF; |
47 | 48 | |
48 | 49 | public static final short ERROR_BAD_XSLT_STYLESHEET = 0x3801; |
@@ -2,11 +2,13 @@ | ||
2 | 2 | |
3 | 3 | import java.awt.Shape; |
4 | 4 | import java.awt.geom.AffineTransform; |
5 | +import java.awt.geom.GeneralPath; | |
5 | 6 | |
6 | 7 | import jp.cssj.homare.style.box.content.Container; |
7 | 8 | import jp.cssj.homare.style.box.content.FlowContainer; |
8 | 9 | import jp.cssj.homare.style.box.impl.PageBox; |
9 | 10 | import jp.cssj.homare.style.box.params.AbstractTextParams; |
11 | +import jp.cssj.homare.style.box.params.Background; | |
10 | 12 | import jp.cssj.homare.style.box.params.BlockParams; |
11 | 13 | import jp.cssj.homare.style.box.params.Dimension; |
12 | 14 | import jp.cssj.homare.style.box.params.Params; |
@@ -125,8 +127,17 @@ | ||
125 | 127 | transform = this.transform(transform, x, y); |
126 | 128 | |
127 | 129 | if (this.params.opacity != 0f && this.frame.isVisible()) { |
128 | - Drawable drawable = new AbsoluteRectFrameDrawable(pageBox, clip, this.params.opacity, transform, this.frame, | |
129 | - this.getWidth(), this.getHeight()); | |
130 | + final Shape textClip; | |
131 | + if (this.getBlockParams().frame.background.getBackgroundClip() == Background.TEXT) { | |
132 | + final GeneralPath path = new GeneralPath(); | |
133 | + this.textShape(pageBox, path, transform, x, y); | |
134 | + textClip = path; | |
135 | + } | |
136 | + else { | |
137 | + textClip = null; | |
138 | + } | |
139 | + final Drawable drawable = new AbsoluteRectFrameDrawable(pageBox, clip, this.params.opacity, transform, this.frame, | |
140 | + this.getWidth(), this.getHeight(), textClip); | |
130 | 141 | drawer.visitDrawable(drawable, x, y); |
131 | 142 | } |
132 | 143 |
@@ -136,6 +147,7 @@ | ||
136 | 147 | y += this.frame.getFrameTop(); |
137 | 148 | this.container.drawFlowFrames(pageBox, drawer, clip, transform, x, y); |
138 | 149 | } |
150 | + | |
139 | 151 | |
140 | 152 | public void draw(PageBox pageBox, Drawer drawer, Visitor visitor, Shape clip, AffineTransform transform, |
141 | 153 | double contextX, double contextY, double x, double y) { |
@@ -2,6 +2,7 @@ | ||
2 | 2 | |
3 | 3 | import java.awt.Shape; |
4 | 4 | import java.awt.geom.AffineTransform; |
5 | +import java.awt.geom.GeneralPath; | |
5 | 6 | import java.awt.geom.Rectangle2D; |
6 | 7 | |
7 | 8 | import jp.cssj.homare.style.box.content.BreakMode; |
@@ -326,6 +327,15 @@ | ||
326 | 327 | public final void getText(StringBuffer textBuff) { |
327 | 328 | this.container.getText(textBuff); |
328 | 329 | } |
330 | + | |
331 | + public final void textShape(PageBox pageBox, GeneralPath path, AffineTransform transform, double x, double y) { | |
332 | + x += this.offsetX; | |
333 | + y += this.offsetY; | |
334 | + transform = this.transform(transform, x, y); | |
335 | + x += this.frame.getFrameLeft(); | |
336 | + y += this.frame.getFrameTop(); | |
337 | + this.container.textShape(pageBox, path, transform, x, y); | |
338 | + } | |
329 | 339 | |
330 | 340 | public void restyle(BlockBuilder builder, int depth) { |
331 | 341 | this.container.restyle(builder, depth, false); |
@@ -1,5 +1,9 @@ | ||
1 | 1 | package jp.cssj.homare.style.box; |
2 | 2 | |
3 | +import java.awt.geom.AffineTransform; | |
4 | +import java.awt.geom.GeneralPath; | |
5 | + | |
6 | +import jp.cssj.homare.style.box.impl.PageBox; | |
3 | 7 | import jp.cssj.homare.style.box.params.InnerTableParams; |
4 | 8 | import jp.cssj.homare.style.box.params.Params; |
5 | 9 | import jp.cssj.homare.style.box.params.TableParams; |
@@ -49,4 +53,8 @@ | ||
49 | 53 | public final double getInnerHeight() { |
50 | 54 | return this.getHeight(); |
51 | 55 | } |
56 | + | |
57 | + public void textShape(PageBox pageBox, GeneralPath path, AffineTransform transform, double x, double d) { | |
58 | + // TODO | |
59 | + } | |
52 | 60 | } |
@@ -2,6 +2,7 @@ | ||
2 | 2 | |
3 | 3 | import java.awt.Shape; |
4 | 4 | import java.awt.geom.AffineTransform; |
5 | +import java.awt.geom.GeneralPath; | |
5 | 6 | |
6 | 7 | import jp.cssj.homare.style.box.content.JustificationState; |
7 | 8 | import jp.cssj.homare.style.box.impl.LineBox; |
@@ -186,4 +187,23 @@ | ||
186 | 187 | drawer.visitDrawable(drawable, x, y); |
187 | 188 | } |
188 | 189 | } |
190 | + | |
191 | + public void textShape(PageBox pageBox, GeneralPath path, AffineTransform transform, double x, double y) { | |
192 | + switch (this.getLineParams().flow) { | |
193 | + case AbstractTextParams.FLOW_TB: | |
194 | + // 横書き | |
195 | + x += this.lineAlign; | |
196 | + break; | |
197 | + | |
198 | + case AbstractTextParams.FLOW_LR: | |
199 | + case AbstractTextParams.FLOW_RL: | |
200 | + // 縦書き | |
201 | + y += this.lineAlign; | |
202 | + break; | |
203 | + | |
204 | + default: | |
205 | + throw new IllegalStateException(); | |
206 | + } | |
207 | + super.textShape(pageBox, path, transform, x, y); | |
208 | + } | |
189 | 209 | } |
@@ -2,6 +2,7 @@ | ||
2 | 2 | |
3 | 3 | import java.awt.Shape; |
4 | 4 | import java.awt.geom.AffineTransform; |
5 | +import java.awt.geom.GeneralPath; | |
5 | 6 | |
6 | 7 | import jp.cssj.homare.style.box.content.ReplacedBoxImage; |
7 | 8 | import jp.cssj.homare.style.box.impl.PageBox; |
@@ -243,7 +244,7 @@ | ||
243 | 244 | |
244 | 245 | public ReplacedBoxDrawable(PageBox pageBox, Shape clip, float opacity, AffineTransform transform, |
245 | 246 | AbsoluteRectFrame frame, Image image, double width, double height) { |
246 | - super(pageBox, clip, opacity, transform, frame, width, height); | |
247 | + super(pageBox, clip, opacity, transform, frame, width, height, null); | |
247 | 248 | this.image = image; |
248 | 249 | } |
249 | 250 |
@@ -279,6 +280,10 @@ | ||
279 | 280 | textBuff.append(str); |
280 | 281 | } |
281 | 282 | } |
283 | + | |
284 | + public void textShape(PageBox pageBox, GeneralPath path, AffineTransform transform, double x, double d) { | |
285 | + // ignore | |
286 | + } | |
282 | 287 | |
283 | 288 | public final void draw(PageBox pageBox, Drawer drawer, Visitor visitor, Shape clip, AffineTransform transform, |
284 | 289 | double contextX, double contextY, double x, double y) { |
@@ -2,6 +2,7 @@ | ||
2 | 2 | |
3 | 3 | import java.awt.Shape; |
4 | 4 | import java.awt.geom.AffineTransform; |
5 | +import java.awt.geom.GeneralPath; | |
5 | 6 | import java.awt.geom.Line2D; |
6 | 7 | import java.awt.geom.Rectangle2D; |
7 | 8 | import java.util.ArrayList; |
@@ -15,7 +16,6 @@ | ||
15 | 16 | import jp.cssj.homare.style.box.params.AbsolutePos; |
16 | 17 | import jp.cssj.homare.style.box.params.AbstractLineParams; |
17 | 18 | import jp.cssj.homare.style.box.params.AbstractTextParams; |
18 | -import jp.cssj.homare.style.box.params.Background; | |
19 | 19 | import jp.cssj.homare.style.box.params.BlockParams; |
20 | 20 | import jp.cssj.homare.style.box.params.Decoration; |
21 | 21 | import jp.cssj.homare.style.box.params.InlinePos; |
@@ -28,8 +28,12 @@ | ||
28 | 28 | import jp.cssj.homare.style.util.ByteList; |
29 | 29 | import jp.cssj.homare.style.util.StyleUtils; |
30 | 30 | import jp.cssj.homare.style.visitor.Visitor; |
31 | +import jp.cssj.sakae.font.Font; | |
32 | +import jp.cssj.sakae.font.FontMetricsImpl; | |
33 | +import jp.cssj.sakae.font.ShapedFont; | |
31 | 34 | import jp.cssj.sakae.gc.GC; |
32 | 35 | import jp.cssj.sakae.gc.GraphicsException; |
36 | +import jp.cssj.sakae.gc.font.util.FontUtils; | |
33 | 37 | import jp.cssj.sakae.gc.paint.Color; |
34 | 38 | import jp.cssj.sakae.gc.paint.RGBColor; |
35 | 39 | import jp.cssj.sakae.gc.text.GlyphHandler; |
@@ -176,8 +180,8 @@ | ||
176 | 180 | */ |
177 | 181 | public final void addInline(IInlineBox box) { |
178 | 182 | if (box.getType() == IBox.TYPE_INLINE) { |
179 | - assert this.getParams().element != box.getParams().element : (box.getParams().element + "\n" | |
180 | - + this.getParams() + "\n" + box.getParams()); | |
183 | + assert this.getParams().element != box.getParams().element | |
184 | + : (box.getParams().element + "\n" + this.getParams() + "\n" + box.getParams()); | |
181 | 185 | InlineBox inline = (InlineBox) box; |
182 | 186 | inline.setDecoration(this.decoration); |
183 | 187 | } |
@@ -195,8 +199,7 @@ | ||
195 | 199 | /** |
196 | 200 | * 両あわせのために拡大できるポイントをカウントします。 |
197 | 201 | * |
198 | - * @param state | |
199 | - * TODO | |
202 | + * @param state TODO | |
200 | 203 | * |
201 | 204 | * @return |
202 | 205 | */ |
@@ -472,12 +475,6 @@ | ||
472 | 475 | if (this.params.color != null) { |
473 | 476 | gc.setFillPaint(this.params.color); |
474 | 477 | } |
475 | - if (this.params instanceof BlockParams) { | |
476 | - BlockParams bp = (BlockParams)this.params; | |
477 | - if (bp.frame.background.getBackgroundClip() == Background.TEXT) { | |
478 | - gc.setFillPaint(bp.frame.background.getBackgroundPaint().getPaint(new Rectangle2D.Double(x, y, 0, this.ascent + this.descent))); | |
479 | - } | |
480 | - } | |
481 | 478 | if (this.params.textStrokeWidth != 0) { |
482 | 479 | gc.setLinePattern(GC.STROKE_SOLID); |
483 | 480 | gc.setLineWidth(this.params.textStrokeWidth); |
@@ -866,6 +863,152 @@ | ||
866 | 863 | } |
867 | 864 | } |
868 | 865 | |
866 | + public void textShape(PageBox pageBox, GeneralPath path, AffineTransform transform, double x, double y) { | |
867 | + if (this.types == null || this.types.isEmpty()) { | |
868 | + return; | |
869 | + } | |
870 | + double xx = x, yy = y; | |
871 | + | |
872 | + final AbstractTextParams lineParams = this.getTextParams(); | |
873 | + final boolean vertical = StyleUtils.isVertical(lineParams.flow); | |
874 | + // テキストとインラインの描画 | |
875 | + for (int i = 0; i < this.types.size(); ++i) { | |
876 | + switch (this.types.get(i)) { | |
877 | + case TYPE_TEXT: { | |
878 | + // テキスト | |
879 | + Text text = (Text) this.contents.get(i); | |
880 | + Font font = ((FontMetricsImpl) text.getFontMetrics()).getFont(); | |
881 | + if (vertical) { | |
882 | + // 縦書き | |
883 | + if (font instanceof ShapedFont) { | |
884 | + AffineTransform at = AffineTransform.getTranslateInstance(xx + this.descent, yy); | |
885 | + at.preConcatenate(transform); | |
886 | + FontUtils.addTextPath(path, (ShapedFont)font, text, at); | |
887 | + } | |
888 | + else { | |
889 | + pageBox.getUserAgent().message(MessageCodes.WARN_MISSING_FONT_OUTLINE, | |
890 | + new String(text.getChars(), 0, text.getCLen())); | |
891 | + } | |
892 | + yy += text.getAdvance(); | |
893 | + } else { | |
894 | + // 横書き | |
895 | + if (font instanceof ShapedFont) { | |
896 | + AffineTransform at = AffineTransform.getTranslateInstance(xx, yy + this.ascent); | |
897 | + at.preConcatenate(transform); | |
898 | + FontUtils.addTextPath(path, (ShapedFont)font, text, at); | |
899 | + } | |
900 | + else { | |
901 | + pageBox.getUserAgent().message(MessageCodes.WARN_MISSING_FONT_OUTLINE, | |
902 | + new String(text.getChars(), 0, text.getCLen())); | |
903 | + } | |
904 | + xx += text.getAdvance(); | |
905 | + } | |
906 | + } | |
907 | + break; | |
908 | + | |
909 | + case TYPE_INLINE: { | |
910 | + // インライン | |
911 | + final Inline inline = (Inline) this.contents.get(i); | |
912 | + final IInlineBox inlineBox = inline.box; | |
913 | + double ascent; | |
914 | + switch (inlineBox.getType()) { | |
915 | + case IBox.TYPE_INLINE: { | |
916 | + // 普通のインライン | |
917 | + final InlineBox box = (InlineBox) inlineBox; | |
918 | + ascent = box.getAscent(); | |
919 | + } | |
920 | + break; | |
921 | + case IBox.TYPE_BLOCK: { | |
922 | + // インラインブロック | |
923 | + double descent; | |
924 | + AbstractContainerBox box = (AbstractContainerBox) inlineBox; | |
925 | + BlockParams params = box.getBlockParams(); | |
926 | + if (vertical) { | |
927 | + // 縦書き | |
928 | + if (params.flow == AbstractTextParams.FLOW_RL || params.flow == AbstractTextParams.FLOW_LR) { | |
929 | + descent = box.getLastDescent(); | |
930 | + if (StyleUtils.isNone(descent)) { | |
931 | + descent = inlineBox.getWidth() / 2.0; | |
932 | + } | |
933 | + } else { | |
934 | + // 縦中横 | |
935 | + descent = inlineBox.getWidth() / 2.0; | |
936 | + } | |
937 | + ascent = inlineBox.getWidth() - descent; | |
938 | + } else { | |
939 | + // 横書き | |
940 | + if (params.flow == AbstractTextParams.FLOW_TB) { | |
941 | + descent = box.getLastDescent(); | |
942 | + if (StyleUtils.isNone(descent)) { | |
943 | + descent = 0; | |
944 | + } | |
945 | + } else { | |
946 | + // 横中縦 | |
947 | + descent = 0; | |
948 | + } | |
949 | + ascent = inlineBox.getHeight() - descent; | |
950 | + } | |
951 | + } | |
952 | + break; | |
953 | + case IBox.TYPE_REPLACED: { | |
954 | + // 画像 | |
955 | + if (vertical) { | |
956 | + // 縦書き | |
957 | + ascent = inlineBox.getWidth() / 2.0; | |
958 | + } else { | |
959 | + // 横書き | |
960 | + ascent = inlineBox.getHeight(); | |
961 | + } | |
962 | + } | |
963 | + break; | |
964 | + default: | |
965 | + throw new IllegalStateException(); | |
966 | + } | |
967 | + | |
968 | + // ベースラインに合わせる | |
969 | + // インラインのアセントはベースラインから内変への長さなので | |
970 | + // 境界とマージンを考慮する | |
971 | + double voffset = (ascent - this.ascent); | |
972 | + // System.err.println(ascent + "/" + this.ascent + "/" | |
973 | + // + inline.verticalAlign); | |
974 | + if (vertical) { | |
975 | + // 縦書き(日本) | |
976 | + voffset += (this.getWidth() - inlineBox.getWidth()); | |
977 | + inlineBox.textShape(pageBox, path, transform, xx + voffset + inline.verticalAlign, yy); | |
978 | + yy += inlineBox.getHeight(); | |
979 | + } else { | |
980 | + // 横書き | |
981 | + inlineBox.textShape(pageBox, path, transform, xx, yy - voffset - inline.verticalAlign); | |
982 | + xx += inlineBox.getWidth(); | |
983 | + } | |
984 | + } | |
985 | + break; | |
986 | + | |
987 | + case TYPE_ABSOLUTE: { | |
988 | + // 絶対配置 | |
989 | + // ignore | |
990 | + } | |
991 | + break; | |
992 | + | |
993 | + case TYPE_CONTROL: { | |
994 | + // 空白 | |
995 | + Control control = (Control) this.contents.get(i); | |
996 | + if (vertical) { | |
997 | + // 縦書き | |
998 | + yy += control.getAdvance(); | |
999 | + } else { | |
1000 | + // 横書き | |
1001 | + xx += control.getAdvance(); | |
1002 | + } | |
1003 | + } | |
1004 | + break; | |
1005 | + | |
1006 | + default: | |
1007 | + throw new IllegalStateException(); | |
1008 | + } | |
1009 | + } | |
1010 | + } | |
1011 | + | |
869 | 1012 | public final double getAscent() { |
870 | 1013 | return this.ascent; |
871 | 1014 | } |
@@ -2,6 +2,7 @@ | ||
2 | 2 | |
3 | 3 | import java.awt.Shape; |
4 | 4 | import java.awt.geom.AffineTransform; |
5 | +import java.awt.geom.GeneralPath; | |
5 | 6 | |
6 | 7 | import jp.cssj.homare.style.box.impl.PageBox; |
7 | 8 | import jp.cssj.homare.style.box.params.Params; |
@@ -109,4 +110,6 @@ | ||
109 | 110 | * 内部のテキストを返します。 |
110 | 111 | */ |
111 | 112 | public void getText(StringBuffer textBuff); |
113 | + | |
114 | + public void textShape(PageBox pageBox, GeneralPath path, AffineTransform transform, double x, double d); | |
112 | 115 | } |
\ No newline at end of file |
@@ -2,6 +2,7 @@ | ||
2 | 2 | |
3 | 3 | import java.awt.Shape; |
4 | 4 | import java.awt.geom.AffineTransform; |
5 | +import java.awt.geom.GeneralPath; | |
5 | 6 | import java.util.ArrayList; |
6 | 7 | import java.util.List; |
7 | 8 |
@@ -222,6 +223,10 @@ | ||
222 | 223 | container.getText(textBuff); |
223 | 224 | } |
224 | 225 | } |
226 | + | |
227 | + public void textShape(PageBox pageBox, GeneralPath path, AffineTransform transform, double x, double y) { | |
228 | + // TODO | |
229 | + } | |
225 | 230 | |
226 | 231 | public boolean hasFloatings() { |
227 | 232 | for (int i = 0; i < this.columns.size(); ++i) { |
@@ -2,6 +2,7 @@ | ||
2 | 2 | |
3 | 3 | import java.awt.Shape; |
4 | 4 | import java.awt.geom.AffineTransform; |
5 | +import java.awt.geom.GeneralPath; | |
5 | 6 | |
6 | 7 | import jp.cssj.homare.style.box.AbstractContainerBox; |
7 | 8 | import jp.cssj.homare.style.box.IAbsoluteBox; |
@@ -65,5 +66,7 @@ | ||
65 | 66 | |
66 | 67 | public void getText(StringBuffer textBuff); |
67 | 68 | |
69 | + public void textShape(PageBox pageBox, GeneralPath path, AffineTransform transform, double x, double y); | |
70 | + | |
68 | 71 | public void restyle(BlockBuilder builder, int depth, boolean restyleAbsolutes); |
69 | 72 | } |
@@ -2,6 +2,7 @@ | ||
2 | 2 | |
3 | 3 | import java.awt.Shape; |
4 | 4 | import java.awt.geom.AffineTransform; |
5 | +import java.awt.geom.GeneralPath; | |
5 | 6 | import java.util.ArrayList; |
6 | 7 | import java.util.Collections; |
7 | 8 | import java.util.List; |
@@ -449,34 +450,34 @@ | ||
449 | 450 | } |
450 | 451 | } |
451 | 452 | |
452 | -// public final void textShape(GeneralPath path, double x, double y) { | |
453 | -// if (this.flows == null) { | |
454 | -// return; | |
455 | -// } | |
456 | -// switch (this.box.getBlockParams().flow) { | |
457 | -// case AbstractTextParams.FLOW_TB: | |
458 | -// // 横書き | |
459 | -// // 通常のフロー | |
460 | -// for (int i = 0; i < this.flows.size(); ++i) { | |
461 | -// Flow c = (Flow) this.flows.get(i); | |
462 | -// c.box.textShape(path, x, y + c.pageAxis); | |
463 | -// } | |
464 | -// break; | |
465 | -// case AbstractTextParams.FLOW_RL: | |
466 | -// case AbstractTextParams.FLOW_LR: | |
467 | -// // 縦書き | |
468 | -// x += this.box.getInnerWidth(); | |
469 | -// for (int i = 0; i < this.flows.size(); ++i) { | |
470 | -// // 通常のフロー | |
471 | -// Flow c = (Flow) this.flows.get(i); | |
472 | -// c.box.textShape(path, | |
473 | -// x - c.pageAxis - c.box.getWidth(), y); | |
474 | -// } | |
475 | -// break; | |
476 | -// default: | |
477 | -// throw new IllegalStateException(); | |
478 | -// } | |
479 | -// } | |
453 | + public final void textShape(PageBox pageBox, GeneralPath path, AffineTransform transform, double x, double y) { | |
454 | + if (this.flows == null) { | |
455 | + return; | |
456 | + } | |
457 | + switch (this.box.getBlockParams().flow) { | |
458 | + case AbstractTextParams.FLOW_TB: | |
459 | + // 横書き | |
460 | + // 通常のフロー | |
461 | + for (int i = 0; i < this.flows.size(); ++i) { | |
462 | + Flow c = (Flow) this.flows.get(i); | |
463 | + c.box.textShape(pageBox, path, transform, x, y + c.pageAxis); | |
464 | + } | |
465 | + break; | |
466 | + case AbstractTextParams.FLOW_RL: | |
467 | + case AbstractTextParams.FLOW_LR: | |
468 | + // 縦書き | |
469 | + x += this.box.getInnerWidth(); | |
470 | + for (int i = 0; i < this.flows.size(); ++i) { | |
471 | + // 通常のフロー | |
472 | + Flow c = (Flow) this.flows.get(i); | |
473 | + c.box.textShape(pageBox, | |
474 | + path, transform, x - c.pageAxis - c.box.getWidth(), y); | |
475 | + } | |
476 | + break; | |
477 | + default: | |
478 | + throw new IllegalStateException(); | |
479 | + } | |
480 | + } | |
480 | 481 | |
481 | 482 | public final void drawFloatings(PageBox pageBox, Drawer drawer, Visitor visitor, Shape clip, |
482 | 483 | AffineTransform transform, double contextX, double contextY, double x, double y) { |
@@ -47,7 +47,7 @@ | ||
47 | 47 | double contextX, double contextY, double x, double y) { |
48 | 48 | // 背景は最初の行だけ描画する |
49 | 49 | if (this.params.opacity != 0 && this.params.background.isVisible()) { |
50 | - Drawable drawable = new BackgroundDrawable(clip, pageBox, this.params.opacity, transform, | |
50 | + Drawable drawable = new BackgroundDrawable(pageBox, clip, this.params.opacity, transform, | |
51 | 51 | this.params.background, this.getWidth(), this.getHeight()); |
52 | 52 | drawer.visitDrawable(drawable, x, y); |
53 | 53 | } |
@@ -250,7 +250,7 @@ | ||
250 | 250 | |
251 | 251 | if (this.frame.isVisible()) { |
252 | 252 | Drawable drawable = new AbsoluteRectFrameDrawable(pageBox, clip, this.params.opacity, transform, |
253 | - this.frame, this.getWidth(), this.getHeight()); | |
253 | + this.frame, this.getWidth(), this.getHeight(), null); // TODO textClip | |
254 | 254 | drawer.visitDrawable(drawable, x, y); |
255 | 255 | } |
256 | 256 | if (StyleUtils.isVertical(this.getTextParams().flow)) { |
@@ -2,6 +2,7 @@ | ||
2 | 2 | |
3 | 3 | import java.awt.Shape; |
4 | 4 | import java.awt.geom.AffineTransform; |
5 | +import java.awt.geom.GeneralPath; | |
5 | 6 | import java.util.ArrayList; |
6 | 7 | import java.util.List; |
7 | 8 |
@@ -449,6 +450,10 @@ | ||
449 | 450 | this.footerGroupBox.getText(textBuff); |
450 | 451 | } |
451 | 452 | } |
453 | + | |
454 | + public void textShape(PageBox pageBox, GeneralPath path, AffineTransform transform, double x, double d) { | |
455 | + // TODO | |
456 | + } | |
452 | 457 | |
453 | 458 | protected static class BorderDrawable extends AbstractDrawable { |
454 | 459 | protected final RectBorder border; |
@@ -359,7 +359,7 @@ | ||
359 | 359 | |
360 | 360 | public void innerDraw(GC gc, double x, double y) throws GraphicsException { |
361 | 361 | if (this.collapse) { |
362 | - this.background.draw(gc, x, y, this.width, this.height, this.border, this.padding); | |
362 | + this.background.draw(gc, x, y, this.width, this.height, this.border, this.padding, null);// TODO text clip | |
363 | 363 | } else { |
364 | 364 | x += this.spacing.left; |
365 | 365 | y += this.spacing.top; |
@@ -366,7 +366,7 @@ | ||
366 | 366 | double width = this.width - this.spacing.getFrameWidth(); |
367 | 367 | double height = this.height - this.spacing.getFrameHeight(); |
368 | 368 | if (width >= 0 || height >= 0) { |
369 | - this.background.draw(gc, x, y, width, height, this.border, this.padding); | |
369 | + this.background.draw(gc, x, y, width, height, this.border, this.padding, null);// TODO text clip | |
370 | 370 | this.border.draw(gc, x, y, width, height); |
371 | 371 | } |
372 | 372 | } |
@@ -2,6 +2,7 @@ | ||
2 | 2 | |
3 | 3 | import java.awt.Shape; |
4 | 4 | import java.awt.geom.AffineTransform; |
5 | +import java.awt.geom.GeneralPath; | |
5 | 6 | import java.util.ArrayList; |
6 | 7 | import java.util.List; |
7 | 8 |
@@ -216,7 +217,6 @@ | ||
216 | 217 | for (int i = 0; i < this.lines.size(); ++i) { |
217 | 218 | Line line = (Line) this.lines.get(i); |
218 | 219 | AbstractLineBox lineBox = line.box; |
219 | - | |
220 | 220 | // 描画 |
221 | 221 | if (StyleUtils.isVertical(this.params.flow)) { |
222 | 222 | // 縦書き |
@@ -229,6 +229,21 @@ | ||
229 | 229 | } |
230 | 230 | } |
231 | 231 | |
232 | + public void textShape(PageBox pageBox, GeneralPath path, AffineTransform transform, double x, double y) { | |
233 | + for (int i = 0; i < this.lines.size(); ++i) { | |
234 | + Line line = (Line) this.lines.get(i); | |
235 | + AbstractLineBox lineBox = line.box; | |
236 | + // 描画 | |
237 | + if (StyleUtils.isVertical(this.params.flow)) { | |
238 | + // 縦書き | |
239 | + lineBox.textShape(pageBox, path, transform, x + this.getPageSize() - line.getPageEnd(), y); | |
240 | + } else { | |
241 | + // 横書き | |
242 | + lineBox.textShape(pageBox, path, transform, x, y + line.pageAxis); | |
243 | + } | |
244 | + } | |
245 | + } | |
246 | + | |
232 | 247 | public final IPageBreakableBox splitPageAxis(double pageLimit, BreakMode mode, byte flags) { |
233 | 248 | assert (!this.lines.isEmpty()); |
234 | 249 | // System.err.println("TBB A: " +flags + "/" + mode + "/" + pageLimit |
@@ -96,14 +96,8 @@ | ||
96 | 96 | * @param border TODO |
97 | 97 | * @throws GraphicsException TODO |
98 | 98 | */ |
99 | - public void draw(GC gc, double x, double y, double width, double height, RectBorder border, Insets padding) throws GraphicsException { | |
99 | + public void draw(GC gc, double x, double y, double width, double height, RectBorder border, Insets padding, Shape textClip) throws GraphicsException { | |
100 | 100 | /* NoAndroid begin */ |
101 | - if (this.backgroundClip == TEXT) { | |
102 | - gc.begin(); | |
103 | - gc.end(); | |
104 | - return; | |
105 | - } | |
106 | - | |
107 | 101 | double pbLeft = border == null ? 0 : border.getLeft().width; |
108 | 102 | double pbTop = border == null ? 0 : border.getTop().width; |
109 | 103 | double pbRight = border == null ? 0 : border.getRight().width; |
@@ -114,8 +108,12 @@ | ||
114 | 108 | double ppBottom = padding == null ? 0 : padding.getBottom(); |
115 | 109 | |
116 | 110 | final Shape shape; |
117 | - if (border == null) { | |
111 | + if (this.backgroundClip == TEXT && textClip != null) { | |
112 | + shape = textClip; | |
113 | + } | |
114 | + else if (border == null) { | |
118 | 115 | switch (this.backgroundClip) { |
116 | + case TEXT: | |
119 | 117 | case BORDER_BOX: |
120 | 118 | case PADDING_BOX: |
121 | 119 | shape = new Rectangle2D.Double(x, y, width, height); |
@@ -129,6 +127,7 @@ | ||
129 | 127 | } |
130 | 128 | } else { |
131 | 129 | switch (this.backgroundClip) { |
130 | + case TEXT: | |
132 | 131 | case BORDER_BOX: |
133 | 132 | shape = BorderRenderer.SHARED_INSTANCE.getBorderShape(border, x, y, width, height); |
134 | 133 | break; |
@@ -11,16 +11,18 @@ | ||
11 | 11 | public class AbsoluteRectFrameDrawable extends AbstractDrawable { |
12 | 12 | protected final AbsoluteRectFrame frame; |
13 | 13 | protected final double width, height; |
14 | + protected final Shape textClip; | |
14 | 15 | |
15 | 16 | public AbsoluteRectFrameDrawable(PageBox pageBox, Shape clip, float opacity, AffineTransform transform, |
16 | - AbsoluteRectFrame frame, double width, double height) { | |
17 | + AbsoluteRectFrame frame, double width, double height, Shape textClip) { | |
17 | 18 | super(pageBox, clip, opacity, transform); |
18 | 19 | this.frame = frame; |
19 | 20 | this.width = width; |
20 | 21 | this.height = height; |
22 | + this.textClip = textClip; | |
21 | 23 | } |
22 | 24 | |
23 | 25 | public void innerDraw(GC gc, double x, double y) throws GraphicsException { |
24 | - this.frame.draw(gc, x, y, this.width, this.height); | |
26 | + this.frame.draw(gc, x, y, this.width, this.height, this.textClip); | |
25 | 27 | } |
26 | 28 | } |
@@ -27,6 +27,6 @@ | ||
27 | 27 | } |
28 | 28 | |
29 | 29 | public void innerDraw(GC gc, double x, double y) throws GraphicsException { |
30 | - this.background.draw(gc, x, y, this.width, this.height, this.border, this.padding); | |
30 | + this.background.draw(gc, x, y, this.width, this.height, this.border, this.padding, null); // TODO text clip | |
31 | 31 | } |
32 | 32 | } |
@@ -12,7 +12,7 @@ | ||
12 | 12 | protected final Background background; |
13 | 13 | protected final double width, height; |
14 | 14 | |
15 | - public BackgroundDrawable(Shape clip, PageBox pageBox, float opacity, AffineTransform transform, | |
15 | + public BackgroundDrawable(PageBox pageBox, Shape clip, float opacity, AffineTransform transform, | |
16 | 16 | Background background, double width, double height) { |
17 | 17 | super(pageBox, clip, opacity, transform); |
18 | 18 | this.background = background; |
@@ -21,6 +21,6 @@ | ||
21 | 21 | } |
22 | 22 | |
23 | 23 | public void innerDraw(GC gc, double x, double y) throws GraphicsException { |
24 | - this.background.draw(gc, x, y, this.width, this.height, null, null); | |
24 | + this.background.draw(gc, x, y, this.width, this.height, null, null, null);// TODO text clip | |
25 | 25 | } |
26 | 26 | } |
@@ -1,5 +1,7 @@ | ||
1 | 1 | package jp.cssj.homare.style.part; |
2 | 2 | |
3 | +import java.awt.Shape; | |
4 | + | |
3 | 5 | import jp.cssj.homare.style.box.params.RectFrame; |
4 | 6 | import jp.cssj.homare.style.util.StyleUtils; |
5 | 7 | import jp.cssj.sakae.gc.GC; |
@@ -64,7 +66,7 @@ | ||
64 | 66 | return this.frame.isVisible(); |
65 | 67 | } |
66 | 68 | |
67 | - public void draw(GC gc, double x, double y, double width, double height) throws GraphicsException { | |
69 | + public void draw(GC gc, double x, double y, double width, double height, Shape textClip) throws GraphicsException { | |
68 | 70 | assert !StyleUtils.isNone(x) : "Undefined x"; |
69 | 71 | assert !StyleUtils.isNone(y) : "Undefined y"; |
70 | 72 | assert !StyleUtils.isNone(width) : "Undefined width"; |
@@ -73,7 +75,7 @@ | ||
73 | 75 | y += this.margin.top; |
74 | 76 | width -= this.margin.getFrameWidth(); |
75 | 77 | height -= this.margin.getFrameHeight(); |
76 | - this.frame.background.draw(gc, x, y, width, height, this.frame.border, this.frame.padding); | |
78 | + this.frame.background.draw(gc, x, y, width, height, this.frame.border, this.frame.padding, textClip); | |
77 | 79 | this.frame.border.draw(gc, x, y, width, height); |
78 | 80 | } |
79 | 81 |
@@ -9,7 +9,7 @@ | ||
9 | 9 | <groupId>net.zamasoft</groupId> |
10 | 10 | <artifactId>sakae</artifactId> |
11 | 11 | <packaging>pom</packaging> |
12 | - <version>0.9.9</version> | |
12 | + <version>1.0.0</version> | |
13 | 13 | <name>Sakae</name> |
14 | 14 | <description>縦書きテキストに対応した、シンプルなグラフィックコンテキストです。</description> |
15 | 15 | <url>https://copper.osdn.jp/sakae/</url> |
@@ -106,6 +106,6 @@ | ||
106 | 106 | <parent> |
107 | 107 | <groupId>net.zamasoft</groupId> |
108 | 108 | <artifactId>sakae</artifactId> |
109 | - <version>0.9.9</version> | |
109 | + <version>1.0.0</version> | |
110 | 110 | </parent> |
111 | 111 | </project> |
\ No newline at end of file |
@@ -62,6 +62,97 @@ | ||
62 | 62 | } |
63 | 63 | |
64 | 64 | /** |
65 | + * テキストをパスに追加します。絵文字は除外されます。 | |
66 | + * | |
67 | + * @param path | |
68 | + * @param font | |
69 | + * @param text | |
70 | + */ | |
71 | + public static void addTextPath(final GeneralPath path, ShapedFont font, Text text, AffineTransform transform) { | |
72 | + FontStyle fontStyle = text.getFontStyle(); | |
73 | + byte direction = fontStyle.getDirection(); | |
74 | + double fontSize = fontStyle.getSize(); | |
75 | + int glen = text.getGLen(); | |
76 | + int[] gids = text.getGIDs(); | |
77 | + double letterSpacing = text.getLetterSpacing(); | |
78 | + double[] xadvances = text.getXAdvances(false); | |
79 | + FontMetrics fm = text.getFontMetrics(); | |
80 | + | |
81 | + double s = fontSize / FontSource.DEFAULT_UNITS_PER_EM; | |
82 | + AffineTransform at = AffineTransform.getScaleInstance(s, s); | |
83 | + | |
84 | + boolean verticalFont = direction == FontStyle.DIRECTION_TB && font.getFontSource().getDirection() == direction; | |
85 | + AffineTransform oblique = null; | |
86 | + short style = fontStyle.getStyle(); | |
87 | + if (style != FontStyle.FONT_STYLE_NORMAL && !font.getFontSource().isItalic()) { | |
88 | + // 自前でイタリックを再現する | |
89 | + if (verticalFont) { | |
90 | + oblique = AffineTransform.getShearInstance(0, 0.25); | |
91 | + } else { | |
92 | + oblique = AffineTransform.getShearInstance(-0.25, 0); | |
93 | + } | |
94 | + } | |
95 | + | |
96 | + if (verticalFont) { | |
97 | + // 縦書きモード | |
98 | + // 縦書き対応フォント | |
99 | + at.preConcatenate(AffineTransform.getTranslateInstance(-fontSize / 2.0, fontSize * 0.88)); | |
100 | + int pgid = 0; | |
101 | + for (int i = 0; i < glen; ++i) { | |
102 | + int gid = gids[i]; | |
103 | + if (i > 0) { | |
104 | + double dy = fm.getAdvance(pgid) + letterSpacing; | |
105 | + dy -= fm.getKerning(pgid, gid); | |
106 | + if (xadvances != null) { | |
107 | + dy += xadvances[i]; | |
108 | + } | |
109 | + at.preConcatenate(AffineTransform.getTranslateInstance(0, dy)); | |
110 | + } | |
111 | + pgid = gid; | |
112 | + Shape shape = ((ShapedFont) font).getShapeByGID(gid); | |
113 | + if (shape != null) { | |
114 | + AffineTransform at2 = new AffineTransform(transform); | |
115 | + double width = (fontSize - fm.getWidth(gid)) / 2.0; | |
116 | + if (width != 0) { | |
117 | + at2.translate(width, 0); | |
118 | + } | |
119 | + at2.concatenate(at); | |
120 | + if (oblique != null) { | |
121 | + shape = oblique.createTransformedShape(shape); | |
122 | + } | |
123 | + path.append(shape.getPathIterator(at2), false); | |
124 | + } | |
125 | + } | |
126 | + } else { | |
127 | + // 横書き | |
128 | + int pgid = 0; | |
129 | + for (int i = 0; i < glen; ++i) { | |
130 | + final int gid = gids[i]; | |
131 | + if (i > 0) { | |
132 | + double dx = fm.getAdvance(pgid) + letterSpacing; | |
133 | + if (i > 0) { | |
134 | + dx -= fm.getKerning(pgid, gid); | |
135 | + } | |
136 | + if (xadvances != null) { | |
137 | + dx += xadvances[i]; | |
138 | + } | |
139 | + at.preConcatenate(AffineTransform.getTranslateInstance(dx, 0)); | |
140 | + } | |
141 | + AffineTransform at2 = new AffineTransform(transform); | |
142 | + Shape shape = ((ShapedFont) font).getShapeByGID(gid); | |
143 | + if (shape != null) { | |
144 | + at2.concatenate(at); | |
145 | + if (oblique != null) { | |
146 | + shape = oblique.createTransformedShape(shape); | |
147 | + } | |
148 | + path.append(shape.getPathIterator(at2), false); | |
149 | + } | |
150 | + pgid = gid; | |
151 | + } | |
152 | + } | |
153 | + } | |
154 | + | |
155 | + /** | |
65 | 156 | * テキストのアウトラインを直接描画します。 |
66 | 157 | * |
67 | 158 | * @param gc |
@@ -167,10 +258,9 @@ | ||
167 | 258 | } |
168 | 259 | path.append(shape.getPathIterator(at2), false); |
169 | 260 | } |
261 | + } else { | |
262 | + ((ImageFont) font).drawGlyphForGid(gc, gid, at2); | |
170 | 263 | } |
171 | - else { | |
172 | - ((ImageFont)font).drawGlyphForGid(gc, gid, at2); | |
173 | - } | |
174 | 264 | } |
175 | 265 | } else { |
176 | 266 | if (direction == FontStyle.DIRECTION_TB) { |
@@ -205,11 +295,10 @@ | ||
205 | 295 | } |
206 | 296 | path.append(shape.getPathIterator(at), false); |
207 | 297 | } |
298 | + } else { | |
299 | + ((ImageFont) font).drawGlyphForGid(gc, gid, at); | |
208 | 300 | } |
209 | - else { | |
210 | - ((ImageFont)font).drawGlyphForGid(gc, gid, at); | |
211 | - } | |
212 | - pgid = gid; | |
301 | + pgid = gid; | |
213 | 302 | } |
214 | 303 | } |
215 | 304 | if (path != null) { |
@@ -16,7 +16,7 @@ | ||
16 | 16 | <dependency> |
17 | 17 | <groupId>net.zamasoft</groupId> |
18 | 18 | <artifactId>sakae-core</artifactId> |
19 | - <version>0.9.9</version> | |
19 | + <version>1.0.0</version> | |
20 | 20 | </dependency> |
21 | 21 | <dependency> |
22 | 22 | <groupId>org.apache.xmlgraphics</groupId> |
@@ -173,6 +173,6 @@ | ||
173 | 173 | <parent> |
174 | 174 | <groupId>net.zamasoft</groupId> |
175 | 175 | <artifactId>sakae</artifactId> |
176 | - <version>0.9.9</version> | |
176 | + <version>1.0.0</version> | |
177 | 177 | </parent> |
178 | 178 | </project> |
\ No newline at end of file |