• R/O
  • SSH
  • HTTPS

copper: Commit


Commit MetaInfo

Revision1622 (tree)
Time2022-05-02 15:22:56
Authormiyabe

Log Message

(empty log message)

Change Summary

Incremental Difference

--- copper/trunk/homare/pom.xml (revision 1621)
+++ copper/trunk/homare/pom.xml (revision 1622)
@@ -9,7 +9,7 @@
99 <groupId>net.zamasoft</groupId>
1010 <artifactId>homare</artifactId>
1111 <packaging>jar</packaging>
12- <version>3.2.14</version>
12+ <version>3.2.15</version>
1313 <name>Homare</name>
1414 <description>印刷向けのHTML/CSSレンダリングエンジンです。</description>
1515 <url>https://copper.osdn.jp/homare/</url>
--- copper/trunk/homare/src/main/java/jp/cssj/homare/css/CSSElement.java (revision 1621)
+++ copper/trunk/homare/src/main/java/jp/cssj/homare/css/CSSElement.java (revision 1622)
@@ -20,6 +20,8 @@
2020 public static final byte PC_ODD = 5;
2121 public static final byte PC_FIRST_CHILD = 6;
2222 public static final byte PC_LINK = 7;
23+ public static final byte PC_ROOT = 8;
24+
2325 /**
2426 * 前に文字列がないfirst-childです。
2527 */
--- copper/trunk/homare/src/main/java/jp/cssj/homare/css/CSSProcessor.java (revision 1621)
+++ copper/trunk/homare/src/main/java/jp/cssj/homare/css/CSSProcessor.java (revision 1622)
@@ -18,6 +18,13 @@
1818 import java.util.logging.Level;
1919 import java.util.logging.Logger;
2020
21+/* NoAndroid begin */
22+import org.apache.xerces.xni.XMLLocator;
23+import org.xml.sax.Attributes;
24+import org.xml.sax.Locator;
25+import org.xml.sax.SAXException;
26+import org.xml.sax.helpers.AttributesImpl;
27+
2128 import jp.cssj.cti2.helpers.MimeTypeHelper;
2229 import jp.cssj.homare.css.html.HTMLCodes;
2330 import jp.cssj.homare.css.html.HTMLStyleUtils;
@@ -46,13 +53,6 @@
4653 import jp.cssj.sakae.sac.css.InputSource;
4754 import jp.cssj.sakae.sac.parser.Parser;
4855
49-/* NoAndroid begin */
50-import org.apache.xerces.xni.XMLLocator;
51-import org.xml.sax.Attributes;
52-import org.xml.sax.Locator;
53-import org.xml.sax.SAXException;
54-import org.xml.sax.helpers.AttributesImpl;
55-
5656 /**
5757 * CSSに関する処理命令を処理します。
5858 *
@@ -487,6 +487,11 @@
487487 byte[] pseudoClasses;
488488 {
489489 int len = 0;
490+ boolean htmlRoot = false;
491+ if (XHTML.HTML_ELEM.equals(uri, lName)) {
492+ htmlRoot = true;
493+ ++len;
494+ }
490495 if (this.firstChild) {
491496 ++len;
492497 }
@@ -502,6 +507,9 @@
502507 pseudoClasses = new byte[len];
503508 }
504509
510+ if (htmlRoot) {
511+ pseudoClasses[--len] = CSSElement.PC_ROOT;
512+ }
505513 if (this.firstChild) {
506514 pseudoClasses[--len] = CSSElement.PC_FIRST_CHILD;
507515 }
--- copper/trunk/homare/src/main/java/jp/cssj/homare/css/StyleContext.java (revision 1621)
+++ copper/trunk/homare/src/main/java/jp/cssj/homare/css/StyleContext.java (revision 1622)
@@ -316,6 +316,9 @@
316316 if (pseudoClass.equalsIgnoreCase("right")) {
317317 pc = CSSElement.PC_RIGHT;
318318 }
319+ else if (pseudoClass.equalsIgnoreCase("root")) {
320+ pc = CSSElement.PC_ROOT;
321+ }
319322 break;
320323 }
321324 return ce.isPseudoClass(pc);
--- copper/trunk/homare/src/main/java/jp/cssj/homare/css/property/ElementPropertySet.java (revision 1621)
+++ copper/trunk/homare/src/main/java/jp/cssj/homare/css/property/ElementPropertySet.java (revision 1622)
@@ -81,6 +81,7 @@
8181 import jp.cssj.homare.impl.css.property.Width;
8282 import jp.cssj.homare.impl.css.property.WordSpacing;
8383 import jp.cssj.homare.impl.css.property.ZIndex;
84+import jp.cssj.homare.impl.css.property.css3.BackgroundClip;
8485 import jp.cssj.homare.impl.css.property.css3.BackgroundSize;
8586 import jp.cssj.homare.impl.css.property.css3.BlockFlow;
8687 import jp.cssj.homare.impl.css.property.css3.BorderBottomLeftRadius;
@@ -282,6 +283,7 @@
282283 this.nameToInfo.put("windows", Widows.INFO);
283284
284285 // CSS3
286+ this.put(BackgroundClip.INFO);
285287 this.put(BackgroundSize.INFO_WIDTH);
286288 this.put(BackgroundSize.INFO_HEIGHT);
287289 this.put(BlockFlow.INFO);
@@ -347,6 +349,8 @@
347349 this.nameToInfo.put("-epub-column-rule", ColumnRuleShorthand.INFO);
348350 this.nameToInfo.put("-epub-columns", ColumnsShorthand.INFO);
349351
352+ this.nameToInfo.put("transform", Transform.INFO);
353+ this.nameToInfo.put("transform-origin", TransformOrigin.INFO_X);
350354 this.nameToInfo.put("background-size", BackgroundSize.INFO_WIDTH);
351355 this.nameToInfo.put("block-flow", BlockFlow.INFO);
352356 this.nameToInfo.put("text-align-last", TextAlignLast.INFO);
--- copper/trunk/homare/src/main/java/jp/cssj/homare/css/style/StyleBuilder.java (revision 1621)
+++ copper/trunk/homare/src/main/java/jp/cssj/homare/css/style/StyleBuilder.java (revision 1622)
@@ -124,6 +124,7 @@
124124 import jp.cssj.homare.impl.css.property.Width;
125125 import jp.cssj.homare.impl.css.property.WordSpacing;
126126 import jp.cssj.homare.impl.css.property.ZIndex;
127+import jp.cssj.homare.impl.css.property.css3.BackgroundClip;
127128 import jp.cssj.homare.impl.css.property.css3.BackgroundSize;
128129 import jp.cssj.homare.impl.css.property.css3.BlockFlow;
129130 import jp.cssj.homare.impl.css.property.css3.BorderBottomLeftRadius;
@@ -816,7 +817,7 @@
816817 } else {
817818 backgroundImage = null;
818819 }
819- Background background = Background.create(BackgroundColor.get(style), backgroundImage);
820+ Background background = Background.create(BackgroundColor.get(style), backgroundImage, BackgroundClip.get(style));
820821 return background;
821822 }
822823
@@ -1288,8 +1289,7 @@
12881289 scope.reset(name, value);
12891290 continue;
12901291 }
1291- scope = pc.getCounterScope(depth, true);
1292- scope.reset(name, value);
1292+ pc.getCounterScope(depth, true).reset(name, value);
12931293 }
12941294 }
12951295
@@ -1805,7 +1805,7 @@
18051805 boolean htmlRoot = false;
18061806 if (!this.inBody && this.htmlRootBlock == null) {
18071807 final CSSElement ce = style.getCSSElement();
1808- if (XHTML.HTML_ELEM.equalsElement(ce)) {
1808+ if (ce.isPseudoClass(CSSElement.PC_ROOT)) {
18091809 htmlRoot = true;
18101810 }
18111811 style.set(Display.INFO, DisplayValue.BLOCK_VALUE, CSSStyle.MODE_IMPORTANT);
--- copper/trunk/homare/src/main/java/jp/cssj/homare/css/util/ColorValueUtils.java (revision 1621)
+++ copper/trunk/homare/src/main/java/jp/cssj/homare/css/util/ColorValueUtils.java (revision 1622)
@@ -821,6 +821,8 @@
821821
822822 public static final ColorValue WINDOWTEXT = toColorValue(SystemColor.windowText);
823823
824+ public static final ColorValue TRANSPARENT = RGBAColorValue.createValue(0, 0, 0, 0);
825+
824826 static {
825827 Map<String, ColorValue> map = new HashMap<String, ColorValue>();
826828 map.put("aqua", AQUA);
@@ -1000,6 +1002,8 @@
10001002 map.put("window", WINDOW);
10011003 map.put("windowframe", WINDOWFRAME);
10021004 map.put("windowtext", WINDOWTEXT);
1005+
1006+ map.put("transparent", TRANSPARENT);
10031007
10041008 COLORNAME_TO_CSS_COLOR = Collections.unmodifiableMap(map);
10051009 }
--- copper/trunk/homare/src/main/java/jp/cssj/homare/css/value/css3/BackgroundClipValue.java (nonexistent)
+++ copper/trunk/homare/src/main/java/jp/cssj/homare/css/value/css3/BackgroundClipValue.java (revision 1622)
@@ -0,0 +1,56 @@
1+package jp.cssj.homare.css.value.css3;
2+
3+/**
4+ * @author MIYABE Tatsuhiko
5+ * @version $Id: ColumnFillValue.java 1552 2018-04-26 01:43:24Z miyabe $
6+ */
7+public class BackgroundClipValue implements CSS3Value {
8+ public static final byte BORDER_BOX = 1;
9+
10+ public static final byte PADDING_BOX = 2;
11+
12+ public static final byte CONTENT_BOX = 3;
13+
14+ public static final byte TEXT = 4;
15+
16+ public static final BackgroundClipValue BORDER_BOX_VALUE = new BackgroundClipValue(BORDER_BOX);
17+
18+ public static final BackgroundClipValue PADDING_BOX_VALUE = new BackgroundClipValue(PADDING_BOX);
19+
20+ public static final BackgroundClipValue CONTENT_BOX_VALUE = new BackgroundClipValue(CONTENT_BOX);
21+
22+ public static final BackgroundClipValue TEXT_VALUE = new BackgroundClipValue(TEXT);
23+
24+ private final byte backgroundClip;
25+
26+ private BackgroundClipValue(byte backgroundClip) {
27+ this.backgroundClip = backgroundClip;
28+ }
29+
30+ public short getValueType() {
31+ return TYPE_BACKGROUND_CLIP;
32+ }
33+
34+ public byte getBackgroundClip() {
35+ return this.backgroundClip;
36+ }
37+
38+ public String toString() {
39+ switch (this.backgroundClip) {
40+ case BORDER_BOX:
41+ return "border-box";
42+
43+ case PADDING_BOX:
44+ return "padding-box";
45+
46+ case CONTENT_BOX:
47+ return "content-box";
48+
49+ case TEXT:
50+ return "text";
51+
52+ default:
53+ throw new IllegalStateException();
54+ }
55+ }
56+}
\ No newline at end of file
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
--- copper/trunk/homare/src/main/java/jp/cssj/homare/css/value/css3/CSS3Value.java (revision 1621)
+++ copper/trunk/homare/src/main/java/jp/cssj/homare/css/value/css3/CSS3Value.java (revision 1622)
@@ -27,4 +27,6 @@
2727 public static final short TYPE_WORD_WRAP = 3011;
2828
2929 public static final short TYPE_WORD_BREAK = 3012;
30+
31+ public static final short TYPE_BACKGROUND_CLIP = 3013;
3032 }
\ No newline at end of file
--- copper/trunk/homare/src/main/java/jp/cssj/homare/impl/css/property/css3/BackgroundClip.java (nonexistent)
+++ copper/trunk/homare/src/main/java/jp/cssj/homare/impl/css/property/css3/BackgroundClip.java (revision 1622)
@@ -0,0 +1,62 @@
1+package jp.cssj.homare.impl.css.property.css3;
2+
3+import java.net.URI;
4+
5+import jp.cssj.homare.css.CSSStyle;
6+import jp.cssj.homare.css.property.AbstractPrimitivePropertyInfo;
7+import jp.cssj.homare.css.property.PrimitivePropertyInfo;
8+import jp.cssj.homare.css.property.PropertyException;
9+import jp.cssj.homare.css.value.Value;
10+import jp.cssj.homare.css.value.css3.BackgroundClipValue;
11+import jp.cssj.homare.ua.UserAgent;
12+import jp.cssj.sakae.sac.css.LexicalUnit;
13+
14+/**
15+ * @author MIYABE Tatsuhiko
16+ * @version $Id: ColumnFill.java 1552 2018-04-26 01:43:24Z miyabe $
17+ */
18+public class BackgroundClip extends AbstractPrimitivePropertyInfo {
19+
20+ public static final PrimitivePropertyInfo INFO = new BackgroundClip();
21+
22+ public static byte get(CSSStyle style) {
23+ BackgroundClipValue value = (BackgroundClipValue) style.get(INFO);
24+ return value.getBackgroundClip();
25+ }
26+
27+ protected BackgroundClip() {
28+ super("background-clip");
29+ }
30+
31+ public Value getDefault(CSSStyle style) {
32+ return BackgroundClipValue.BORDER_BOX_VALUE;
33+ }
34+
35+ public boolean isInherited() {
36+ return false;
37+ }
38+
39+ public Value getComputedValue(Value value, CSSStyle style) {
40+ return value;
41+ }
42+
43+ public Value parseProperty(LexicalUnit lu, UserAgent ua, URI uri) throws PropertyException {
44+ switch (lu.getLexicalUnitType()) {
45+ case LexicalUnit.SAC_IDENT:
46+ String ident = lu.getStringValue().toLowerCase();
47+ if (ident.equals("border-box")) {
48+ return BackgroundClipValue.BORDER_BOX_VALUE;
49+ } else if (ident.equals("padding-box")) {
50+ return BackgroundClipValue.PADDING_BOX_VALUE;
51+ } else if (ident.equals("content-box")) {
52+ return BackgroundClipValue.CONTENT_BOX_VALUE;
53+ } /* else if (ident.equals("text")) {
54+ return BackgroundClipValue.TEXT_VALUE;
55+ } */
56+
57+ default:
58+ throw new PropertyException();
59+ }
60+ }
61+
62+}
\ No newline at end of file
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
--- copper/trunk/homare/src/main/java/jp/cssj/homare/impl/css/property/css3/BackgroundSize.java (revision 1621)
+++ copper/trunk/homare/src/main/java/jp/cssj/homare/impl/css/property/css3/BackgroundSize.java (revision 1622)
@@ -123,7 +123,7 @@
123123
124124 lu = lu.getNextLexicalUnit();
125125 if (lu == null) {
126- h = w;
126+ h = AutoValue.AUTO_VALUE;
127127 return new Entry[] { new Entry(BackgroundSize.INFO_WIDTH, w), new Entry(BackgroundSize.INFO_HEIGHT, h) };
128128 }
129129
@@ -141,7 +141,7 @@
141141 }
142142 }
143143 if (h == null) {
144- h = w;
144+ h = AutoValue.AUTO_VALUE;
145145 }
146146 return new Entry[] { new Entry(BackgroundSize.INFO_WIDTH, w), new Entry(BackgroundSize.INFO_HEIGHT, h) };
147147 }
--- copper/trunk/homare/src/main/java/jp/cssj/homare/impl/css/property/shorthand/BackgroundShorthand.java (revision 1621)
+++ copper/trunk/homare/src/main/java/jp/cssj/homare/impl/css/property/shorthand/BackgroundShorthand.java (revision 1622)
@@ -8,9 +8,11 @@
88 import jp.cssj.homare.css.property.ShorthandPropertyInfo;
99 import jp.cssj.homare.css.util.ColorValueUtils;
1010 import jp.cssj.homare.css.util.ValueUtils;
11+import jp.cssj.homare.css.value.AutoValue;
1112 import jp.cssj.homare.css.value.BackgroundAttachmentValue;
1213 import jp.cssj.homare.css.value.BackgroundRepeatValue;
1314 import jp.cssj.homare.css.value.InheritValue;
15+import jp.cssj.homare.css.value.LengthValue;
1416 import jp.cssj.homare.css.value.NoneValue;
1517 import jp.cssj.homare.css.value.PercentageValue;
1618 import jp.cssj.homare.css.value.TransparentValue;
@@ -20,6 +22,7 @@
2022 import jp.cssj.homare.impl.css.property.BackgroundImage;
2123 import jp.cssj.homare.impl.css.property.BackgroundPosition;
2224 import jp.cssj.homare.impl.css.property.BackgroundRepeat;
25+import jp.cssj.homare.impl.css.property.css3.BackgroundSize;
2326 import jp.cssj.homare.message.MessageCodes;
2427 import jp.cssj.homare.ua.UserAgent;
2528 import jp.cssj.sakae.sac.css.LexicalUnit;
@@ -43,6 +46,8 @@
4346 primitives.set(BackgroundRepeat.INFO, InheritValue.INHERIT_VALUE);
4447 primitives.set(BackgroundPosition.INFO_X, InheritValue.INHERIT_VALUE);
4548 primitives.set(BackgroundPosition.INFO_Y, InheritValue.INHERIT_VALUE);
49+ primitives.set(BackgroundSize.INFO_WIDTH, InheritValue.INHERIT_VALUE);
50+ primitives.set(BackgroundSize.INFO_HEIGHT, InheritValue.INHERIT_VALUE);
4651 return;
4752 }
4853
@@ -52,7 +57,9 @@
5257 primitives.set(BackgroundRepeat.INFO, BackgroundRepeatValue.REPEAT_VALUE);
5358 primitives.set(BackgroundPosition.INFO_X, PercentageValue.ZERO);
5459 primitives.set(BackgroundPosition.INFO_Y, PercentageValue.ZERO);
55- boolean color = false, none = false, uriValue = false, repeat = false, attachment = false, position = false;
60+ primitives.set(BackgroundSize.INFO_WIDTH, AutoValue.AUTO_VALUE);
61+ primitives.set(BackgroundSize.INFO_HEIGHT, AutoValue.AUTO_VALUE);
62+ boolean color = false, none = false, uriValue = false, repeat = false, attachment = false, position = false, size = false;
5663 for (; lu != null; lu = lu.getNextLexicalUnit()) {
5764 if (ColorValueUtils.isTransparent(lu)) {
5865 primitives.set(BackgroundColor.INFO, TransparentValue.TRANSPARENT_VALUE);
@@ -109,7 +116,59 @@
109116 primitives.set(BackgroundAttachment.INFO, value);
110117 continue;
111118 }
119+
120+ if (lu.getLexicalUnitType() == LexicalUnit.SAC_OPERATOR_SLASH) {
121+ if (size) {
122+ throw new PropertyException("sizeが2度指定されています");
123+ }
124+ size = true;
125+
126+ Value w, h;
112127
128+ lu = lu.getNextLexicalUnit();
129+ if (ValueUtils.isAuto(lu)) {
130+ w = AutoValue.AUTO_VALUE;
131+ } else {
132+ w = ValueUtils.toPercentage(lu);
133+ if (w == null) {
134+ w = ValueUtils.toLength(ua, lu);
135+ if (w == null || ((LengthValue) w).isNegative()) {
136+ throw new PropertyException();
137+ }
138+ } else if (((PercentageValue) w).isNegative()) {
139+ throw new PropertyException();
140+ }
141+ }
142+
143+ lu = lu.getNextLexicalUnit();
144+ if (lu == null) {
145+ h = AutoValue.AUTO_VALUE;
146+ primitives.set(BackgroundSize.INFO_WIDTH, w);
147+ primitives.set(BackgroundSize.INFO_HEIGHT, h);
148+ continue;
149+ }
150+
151+ if (ValueUtils.isAuto(lu)) {
152+ h = AutoValue.AUTO_VALUE;
153+ } else {
154+ h = ValueUtils.toPercentage(lu);
155+ if (h == null) {
156+ h = ValueUtils.toLength(ua, lu);
157+ if (h != null && ((LengthValue) h).isNegative()) {
158+ throw new PropertyException();
159+ }
160+ } else if (((PercentageValue) h).isNegative()) {
161+ throw new PropertyException();
162+ }
163+ }
164+ if (h == null) {
165+ h = AutoValue.AUTO_VALUE;
166+ }
167+ primitives.set(BackgroundSize.INFO_WIDTH, w);
168+ primitives.set(BackgroundSize.INFO_HEIGHT, h);
169+ continue;
170+ }
171+
113172 if (position) {
114173 throw new PropertyException("positionが2度指定されています");
115174 }
--- copper/trunk/homare/src/main/java/jp/cssj/homare/impl/ua/image/RasterImageLoader.java (revision 1621)
+++ copper/trunk/homare/src/main/java/jp/cssj/homare/impl/ua/image/RasterImageLoader.java (revision 1622)
@@ -9,6 +9,7 @@
99 import javax.imageio.stream.FileCacheImageInputStream;
1010 import javax.imageio.stream.FileImageInputStream;
1111 import javax.imageio.stream.ImageInputStream;
12+import fr.sertelon.media.jpeg.CMYKJPEGImageReader;
1213
1314 import jp.cssj.homare.ua.ImageLoader;
1415 import jp.cssj.homare.ua.UserAgent;
@@ -49,21 +50,43 @@
4950 imageIn = new FileCacheImageInputStream(source.getInputStream(), null);
5051 }
5152 try { // ImageIOによるラスタ画像の取得
53+ CMYKJPEGImageReader cir = null;
5254 Iterator<ImageReader> iri = ImageIO.getImageReaders(imageIn);
5355 ImageReader ir = null;
5456 while (iri != null && iri.hasNext()) {
5557 ir = iri.next();
5658 ir.setInput(imageIn);
57- Iterator<ImageTypeSpecifier> iti = ir.getImageTypes(0);
58- if (iti != null && iti.hasNext()) {
59- break;
59+ try {
60+ Iterator<ImageTypeSpecifier> iti = ir.getImageTypes(0);
61+ if (iti != null && iti.hasNext()) {
62+ imageIn.seek(0);
63+ if (ir instanceof CMYKJPEGImageReader) {
64+ cir = (CMYKJPEGImageReader)ir;
65+ ir = null;
66+ continue;
67+ }
68+ break;
69+ }
70+ } catch (IOException e) {
71+ // ignore
6072 }
6173 ir.dispose();
6274 ir = null;
75+ imageIn.seek(0);
6376 }
6477 if (ir == null) {
65- throw new IOException("ImageIOがサポートしない画像形式です");
78+ if (cir != null) {
79+ ir = cir;
80+ }
81+ else {
82+ throw new IOException("ImageIOがサポートしない画像形式です");
83+ }
6684 }
85+ else {
86+ if (cir != null) {
87+ cir.dispose();
88+ }
89+ }
6790 imageIn.seek(0);
6891 return new RasterImageImpl(G2dUtils.loadImage(ir, imageIn));
6992 } finally {
--- copper/trunk/homare/src/main/java/jp/cssj/homare/impl/ua/svg/MyGVTFont.java (revision 1621)
+++ copper/trunk/homare/src/main/java/jp/cssj/homare/impl/ua/svg/MyGVTFont.java (revision 1622)
@@ -118,7 +118,7 @@
118118 if (clen > 0) {
119119 ti.appendGlyph(this.ch, 0, clen, sgid);
120120 }
121- return new MyGVTGlyphVector(ti, this);
121+ return new MyGVTGlyphVector(ti, this, frc);
122122 }
123123
124124 public GVTGlyphVector createGlyphVector(FontRenderContext frc, char[] text) {
--- copper/trunk/homare/src/main/java/jp/cssj/homare/impl/ua/svg/MyGVTGlyphVector.java (revision 1621)
+++ copper/trunk/homare/src/main/java/jp/cssj/homare/impl/ua/svg/MyGVTGlyphVector.java (revision 1622)
@@ -6,6 +6,7 @@
66 import java.awt.font.GlyphJustificationInfo;
77 import java.awt.font.GlyphMetrics;
88 import java.awt.geom.AffineTransform;
9+import java.awt.geom.GeneralPath;
910 import java.awt.geom.Point2D;
1011 import java.awt.geom.Rectangle2D;
1112 import java.text.AttributedCharacterIterator;
@@ -14,16 +15,23 @@
1415 import org.apache.batik.gvt.font.GVTGlyphMetrics;
1516 import org.apache.batik.gvt.font.GVTGlyphVector;
1617
17-import jp.cssj.sakae.gc.text.Text;
18+import jp.cssj.sakae.font.BBox;
19+import jp.cssj.sakae.font.FontSource;
20+import jp.cssj.sakae.font.ShapedFont;
21+import jp.cssj.sakae.gc.font.FontMetrics;
22+import jp.cssj.sakae.gc.font.FontStyle;
23+import jp.cssj.sakae.gc.text.TextImpl;
1824
1925 public class MyGVTGlyphVector implements GVTGlyphVector {
20- protected final Text text;
21- protected final GVTFont font;
26+ protected final TextImpl text;
27+ protected final MyGVTFont font;
28+ protected final FontRenderContext frc;
2229 protected float[] x, y;
2330
24- public MyGVTGlyphVector(Text text, GVTFont font) {
31+ public MyGVTGlyphVector(TextImpl text, MyGVTFont font, FontRenderContext frc) {
2532 this.text = text;
2633 this.font = font;
34+ this.frc = frc;
2735 // 配列の最後は末尾の位置
2836 this.x = new float[text.getGLen() + 1];
2937 this.y = new float[text.getGLen() + 1];
@@ -107,6 +115,115 @@
107115 return new Point2D.Float(this.x[ix], this.y[ix]);
108116 }
109117
118+ public FontRenderContext getFontRenderContext() {
119+ return this.frc;
120+ }
121+
122+ public Shape getGlyphOutline(int ix) {
123+ if (!(this.font.font instanceof ShapedFont)) {
124+ throw new UnsupportedOperationException();
125+ }
126+ ShapedFont font = (ShapedFont) this.font.font;
127+ return font.getShapeByGID(this.getGlyphCode(ix));
128+ }
129+
130+ public Shape getOutline() {
131+ if (!(this.font.font instanceof ShapedFont)) {
132+ throw new UnsupportedOperationException();
133+ }
134+ ShapedFont font = (ShapedFont) this.font.font;
135+ FontStyle fontStyle = text.getFontStyle();
136+ byte direction = fontStyle.getDirection();
137+ double fontSize = fontStyle.getSize();
138+ int glen = text.getGLen();
139+ int[] gids = text.getGIDs();
140+ double letterSpacing = text.getLetterSpacing();
141+ double[] xadvances = text.getXAdvances(false);
142+ FontMetrics fm = text.getFontMetrics();
143+ AffineTransform at;
144+ {
145+ double s = fontSize / FontSource.DEFAULT_UNITS_PER_EM;
146+ at = AffineTransform.getScaleInstance(s, s);
147+ }
148+
149+ boolean verticalFont = direction == FontStyle.DIRECTION_TB && font.getFontSource().getDirection() == direction;
150+ AffineTransform oblique = null;
151+ short style = fontStyle.getStyle();
152+ if (style != FontStyle.FONT_STYLE_NORMAL && !font.getFontSource().isItalic()) {
153+ // 自前でイタリックを再現する
154+ if (verticalFont) {
155+ oblique = AffineTransform.getShearInstance(0, 0.25);
156+ } else {
157+ oblique = AffineTransform.getShearInstance(-0.25, 0);
158+ }
159+ }
160+
161+ GeneralPath path = new GeneralPath();
162+ if (verticalFont) {
163+ // 縦書きモード
164+ // 縦書き対応フォント
165+ at.concatenate(AffineTransform.getTranslateInstance(-fontSize / 2.0, fontSize * 0.88));
166+ int pgid = 0;
167+ for (int i = 0; i < glen; ++i) {
168+ AffineTransform at2 = at;
169+ int gid = gids[i];
170+ if (i > 0) {
171+ double dy = fm.getAdvance(pgid) + letterSpacing;
172+ dy -= fm.getKerning(pgid, gid);
173+ if (xadvances != null) {
174+ dy += xadvances[i];
175+ }
176+ at.preConcatenate(AffineTransform.getTranslateInstance(0, dy));
177+ }
178+ pgid = gid;
179+ Shape shape = font.getShapeByGID(gid);
180+ if (shape != null) {
181+ double width = (fontSize - fm.getWidth(gid)) / 2.0;
182+ if (width != 0) {
183+ at2 = AffineTransform.getTranslateInstance(width, 0);
184+ at2.concatenate(at);
185+ }
186+ if (oblique != null) {
187+ shape = oblique.createTransformedShape(shape);
188+ }
189+ path.append(shape.getPathIterator(at2), false);
190+ }
191+ }
192+ } else {
193+ if (direction == FontStyle.DIRECTION_TB) {
194+ // 横倒し
195+ at.concatenate(AffineTransform.getRotateInstance(Math.PI / 2.0));
196+ BBox bbox = font.getFontSource().getBBox();
197+ double dy = ((bbox.lly + bbox.ury) * fontSize / FontSource.DEFAULT_UNITS_PER_EM) / 2.0;
198+ at.concatenate(AffineTransform.getTranslateInstance(0, dy));
199+ }
200+ // 横書き
201+ int pgid = 0;
202+ for (int i = 0; i < glen; ++i) {
203+ final int gid = gids[i];
204+ if (i > 0) {
205+ double dx = fm.getAdvance(pgid) + letterSpacing;
206+ if (i > 0) {
207+ dx -= fm.getKerning(pgid, gid);
208+ }
209+ if (xadvances != null) {
210+ dx += xadvances[i];
211+ }
212+ at.preConcatenate(AffineTransform.getTranslateInstance(dx, 0));
213+ }
214+ Shape shape = font.getShapeByGID(gid);
215+ if (shape != null) {
216+ if (oblique != null) {
217+ shape = oblique.createTransformedShape(shape);
218+ }
219+ path.append(shape.getPathIterator(at), false);
220+ }
221+ pgid = gid;
222+ }
223+ }
224+ return path.createTransformedShape(at);
225+ }
226+
110227 public Rectangle2D getGeometricBounds() {
111228 throw new UnsupportedOperationException();
112229 }
@@ -127,22 +244,10 @@
127244 throw new UnsupportedOperationException();
128245 }
129246
130- public FontRenderContext getFontRenderContext() {
131- throw new UnsupportedOperationException();
132- }
133-
134- public Shape getGlyphOutline(int ix) {
135- throw new UnsupportedOperationException();
136- }
137-
138247 public AffineTransform getGlyphTransform(int ix) {
139248 throw new UnsupportedOperationException();
140249 }
141250
142- public Shape getOutline() {
143- throw new UnsupportedOperationException();
144- }
145-
146251 public Shape getOutline(float x, float y) {
147252 throw new UnsupportedOperationException();
148253 }
--- copper/trunk/homare/src/main/java/jp/cssj/homare/style/DocumentBuilder.java (revision 1621)
+++ copper/trunk/homare/src/main/java/jp/cssj/homare/style/DocumentBuilder.java (revision 1622)
@@ -1,5 +1,7 @@
11 package jp.cssj.homare.style;
22
3+import java.text.Normalizer;
4+import java.text.Normalizer.Form;
35 import java.util.ArrayList;
46 import java.util.List;
57
@@ -40,6 +42,7 @@
4042 import jp.cssj.homare.style.builder.impl.TwoPassBlockBuilder;
4143 import jp.cssj.homare.style.builder.impl.TwoPassTableBuilder;
4244 import jp.cssj.homare.style.util.StyleUtils;
45+import jp.cssj.homare.ua.props.UAProps;
4346 import jp.cssj.sakae.util.NumberUtils;
4447
4548 /**
@@ -52,6 +55,8 @@
5255
5356 public static final byte PAGE_MODE_CONTINUOUS = 1;
5457 public static final byte PAGE_MODE_NO_BREAK = 1 << 1;
58+
59+ private final boolean normalizeText;
5560
5661 protected static class ContainerBuilderEntry {
5762 public final Builder builder;
@@ -92,6 +97,7 @@
9297
9398 public DocumentBuilder(PageGenerator pageGenerator) {
9499 this.pageGenerator = pageGenerator;
100+ this.normalizeText = UAProps.INPUT_NORMALIZE_TEXT.getBoolean(pageGenerator.getUserAgent());
95101 }
96102
97103 public void setPageMode(byte pageMode) {
@@ -696,7 +702,15 @@
696702 }
697703 }
698704
699- public void characters(int charOffset, char[] ch, final int off, final int len, boolean lineFeed) {
705+ public void characters(int charOffset, char[] ch, int off, int len, boolean lineFeed) {
706+ if (this.normalizeText) {
707+ String s = new String(ch, off, len);
708+ s = Normalizer.normalize(s, Form.NFC);
709+ ch = s.toCharArray();
710+ off = 0;
711+ len = s.length();
712+ }
713+
700714 if (DEBUG) {
701715 System.err.println(charOffset + "/" + new String(ch, off, len));
702716 }
--- copper/trunk/homare/src/main/java/jp/cssj/homare/style/box/content/CSSVerticalAlignPolicy.java (revision 1621)
+++ copper/trunk/homare/src/main/java/jp/cssj/homare/style/box/content/CSSVerticalAlignPolicy.java (revision 1622)
@@ -86,14 +86,15 @@
8686
8787 case CSSVerticalAlignPolicy.TEXT_TOP: {
8888 // ボックスのフォントの上辺を親ボックスのフォントの上辺に揃える。
89- v = parentBox.getAscent() - ascent - (parentBox.getPageSize() - (ascent + descent)) / 2;
89+ final FontListMetrics flm = parentBox.getTextParams().getFontListMetrics();
90+ v = flm.getMaxAscent() - ascent;
9091 break;
9192 }
9293
9394 case CSSVerticalAlignPolicy.TEXT_BOTTOM: {
9495 // ボックスのフォントの下辺を親要素のフォントの下辺に揃える。
95- v = -(parentBox.getDescent() - descent) + (parentBox.getPageSize() - (ascent + descent)) / 2;
96- // System.out.println(descent+"/"+ascent+"/"+parentBox.getDescent()+"/"+lineBox.getPageSize()+"/"+v);
96+ final FontListMetrics flm = parentBox.getTextParams().getFontListMetrics();
97+ v = -flm.getMaxDescent() + descent;
9798 break;
9899 }
99100
--- copper/trunk/homare/src/main/java/jp/cssj/homare/style/box/impl/TableBox.java (revision 1621)
+++ copper/trunk/homare/src/main/java/jp/cssj/homare/style/box/impl/TableBox.java (revision 1622)
@@ -283,7 +283,7 @@
283283
284284 if (this.params.frame.background.isVisible()) {
285285 Drawable drawable = new BackgroundBorderDrawable(pageBox, clip, this.params.opacity, transform,
286- this.params.frame.background, this.params.frame.border,
286+ this.params.frame.background, this.params.frame.border, this.params.frame.padding,
287287 this.getWidth() - this.frame.getFrameWidth(), this.getHeight() - this.frame.getFrameHeight());
288288 drawer.visitDrawable(drawable, xx, yy);
289289 }
--- copper/trunk/homare/src/main/java/jp/cssj/homare/style/box/impl/TableCellBox.java (revision 1621)
+++ copper/trunk/homare/src/main/java/jp/cssj/homare/style/box/impl/TableCellBox.java (revision 1622)
@@ -11,6 +11,7 @@
1111 import jp.cssj.homare.style.box.params.Background;
1212 import jp.cssj.homare.style.box.params.BlockParams;
1313 import jp.cssj.homare.style.box.params.Dimension;
14+import jp.cssj.homare.style.box.params.Insets;
1415 import jp.cssj.homare.style.box.params.Params;
1516 import jp.cssj.homare.style.box.params.Pos;
1617 import jp.cssj.homare.style.box.params.RectBorder;
@@ -230,7 +231,7 @@
230231
231232 if (this.draw()) {
232233 Drawable drawable = new TableCellBoxDrawable(clip, pageBox, this.params.opacity, transform,
233- this.frame.frame.background, this.frame.frame.border, this.collapse, this.frame.margin,
234+ this.frame.frame.background, this.frame.frame.border, this.frame.frame.padding, this.collapse, this.frame.margin,
234235 this.getWidth(), this.getHeight());
235236 drawer.visitDrawable(drawable, x, y);
236237 }
@@ -349,20 +350,16 @@
349350 protected final AbsoluteInsets spacing;
350351
351352 public TableCellBoxDrawable(Shape clip, PageBox pageBox, float opacity, AffineTransform transform,
352- Background background, RectBorder border, boolean collapse, AbsoluteInsets spacing, double width,
353+ Background background, RectBorder border, Insets padding, boolean collapse, AbsoluteInsets spacing, double width,
353354 double height) {
354- super(pageBox, clip, opacity, transform, background, border, width, height);
355+ super(pageBox, clip, opacity, transform, background, border, padding, width, height);
355356 this.collapse = collapse;
356357 this.spacing = spacing;
357358 }
358359
359360 public void innerDraw(GC gc, double x, double y) throws GraphicsException {
360- double pbLeft = this.border.getLeft().width;
361- double pbTop = this.border.getTop().width;
362- double pbRight = this.border.getRight().width;
363- double pbBottom = this.border.getBottom().width;
364361 if (this.collapse) {
365- this.background.draw(gc, x, y, this.width, this.height, pbLeft, pbTop, pbRight, pbBottom, this.border);
362+ this.background.draw(gc, x, y, this.width, this.height, this.border, this.padding);
366363 } else {
367364 x += this.spacing.left;
368365 y += this.spacing.top;
@@ -369,7 +366,7 @@
369366 double width = this.width - this.spacing.getFrameWidth();
370367 double height = this.height - this.spacing.getFrameHeight();
371368 if (width >= 0 || height >= 0) {
372- this.background.draw(gc, x, y, width, height, pbLeft, pbTop, pbRight, pbBottom, this.border);
369+ this.background.draw(gc, x, y, width, height, this.border, this.padding);
373370 this.border.draw(gc, x, y, width, height);
374371 }
375372 }
--- copper/trunk/homare/src/main/java/jp/cssj/homare/style/box/impl/TableColumnBox.java (revision 1621)
+++ copper/trunk/homare/src/main/java/jp/cssj/homare/style/box/impl/TableColumnBox.java (revision 1622)
@@ -60,7 +60,7 @@
6060 return;
6161 }
6262 Drawable drawable = new BackgroundBorderDrawable(pageBox, clip, this.params.opacity, transform,
63- this.params.background, this.params.border, this.getWidth(), this.getHeight());
63+ this.params.background, this.params.border, null, this.getWidth(), this.getHeight());
6464 drawer.visitDrawable(drawable, x, y);
6565 }
6666
--- copper/trunk/homare/src/main/java/jp/cssj/homare/style/box/impl/TableRowBox.java (revision 1621)
+++ copper/trunk/homare/src/main/java/jp/cssj/homare/style/box/impl/TableRowBox.java (revision 1622)
@@ -190,7 +190,7 @@
190190 }
191191 if (this.params.background.isVisible()) {
192192 Drawable drawable = new BackgroundBorderDrawable(pageBox, clip, this.params.opacity, transform,
193- this.params.background, this.params.border, this.getWidth(), this.getHeight());
193+ this.params.background, this.params.border, null, this.getWidth(), this.getHeight());
194194 drawer.visitDrawable(drawable, x, y);
195195 }
196196 if (this.cells == null) {
--- copper/trunk/homare/src/main/java/jp/cssj/homare/style/box/impl/TableRowGroupBox.java (revision 1621)
+++ copper/trunk/homare/src/main/java/jp/cssj/homare/style/box/impl/TableRowGroupBox.java (revision 1622)
@@ -96,7 +96,7 @@
9696 }
9797 if (this.params.background.isVisible()) {
9898 Drawable drawable = new BackgroundBorderDrawable(pageBox, clip, this.params.opacity, transform,
99- this.params.background, this.params.border, this.getWidth(), this.getHeight());
99+ this.params.background, this.params.border, null, this.getWidth(), this.getHeight());
100100 drawer.visitDrawable(drawable, x, y);
101101 }
102102 if (this.rows == null) {
--- copper/trunk/homare/src/main/java/jp/cssj/homare/style/box/params/Background.java (revision 1621)
+++ copper/trunk/homare/src/main/java/jp/cssj/homare/style/box/params/Background.java (revision 1622)
@@ -18,11 +18,6 @@
1818 */
1919 public class Background {
2020 /**
21- * 無地の背景です。
22- */
23- public static final Background NULL_BACKGROUND = new Background(null, null);
24-
25- /**
2621 * 背景色です。nullの場合は背景を塗りません。
2722 */
2823 private final Color backgroundColor;
@@ -32,16 +27,35 @@
3227 */
3328 private final BackgroundImage backgroundImage;
3429
35- public static Background create(Color backgroundColor, BackgroundImage backgroundImage) {
30+ public static final byte BORDER_BOX = 1;
31+
32+ public static final byte PADDING_BOX = 2;
33+
34+ public static final byte CONTENT_BOX = 3;
35+
36+ public static final byte TEXT = 4;
37+
38+ /**
39+ * 背景の切り取り方法。
40+ */
41+ private final byte backgroundClip;
42+
43+ /**
44+ * 無地の背景です。
45+ */
46+ public static final Background NULL_BACKGROUND = new Background(null, null, BORDER_BOX);
47+
48+ public static Background create(Color backgroundColor, BackgroundImage backgroundImage, byte backgroundCiip) {
3649 if (backgroundColor == null && backgroundImage == null) {
3750 return NULL_BACKGROUND;
3851 }
39- return new Background(backgroundColor, backgroundImage);
52+ return new Background(backgroundColor, backgroundImage, backgroundCiip);
4053 }
4154
42- private Background(Color backgroundColor, BackgroundImage backgroundImage) {
55+ private Background(Color backgroundColor, BackgroundImage backgroundImage, byte backgroundClip) {
4356 this.backgroundColor = backgroundColor;
4457 this.backgroundImage = backgroundImage;
58+ this.backgroundClip = backgroundClip;
4559 }
4660
4761 /**
@@ -63,6 +77,15 @@
6377 }
6478
6579 /**
80+ * 背景の切り抜き方法を返します。
81+ *
82+ * @return
83+ */
84+ public byte getBackgroundCiip() {
85+ return this.backgroundClip;
86+ }
87+
88+ /**
6689 * 背景を描画します。
6790 *
6891 * @param gc
@@ -70,19 +93,50 @@
7093 * @param y
7194 * @param width
7295 * @param height
73- * @param border
74- * TODO
75- * @throws GraphicsException
76- * TODO
96+ * @param border TODO
97+ * @throws GraphicsException TODO
7798 */
78- public void draw(GC gc, double x, double y, double width, double height, double pbLeft, double pbTop,
79- double pbRight, double pbBottom, RectBorder border) throws GraphicsException {
99+ public void draw(GC gc, double x, double y, double width, double height, RectBorder border, Insets padding) throws GraphicsException {
80100 /* NoAndroid begin */
101+ double pbLeft = border == null ? 0 : border.getLeft().width;
102+ double pbTop = border == null ? 0 : border.getTop().width;
103+ double pbRight = border == null ? 0 : border.getRight().width;
104+ double pbBottom = border == null ? 0 : border.getBottom().width;
105+ double ppLeft = padding == null ? 0 : padding.getLeft();
106+ double ppTop = padding == null ? 0 : padding.getTop();
107+ double ppRight = padding == null ? 0 : padding.getRight();
108+ double ppBottom = padding == null ? 0 : padding.getBottom();
109+
81110 final Shape shape;
82111 if (border == null) {
83- shape = new Rectangle2D.Double(x, y, width, height);
112+ switch (this.backgroundClip) {
113+ case BORDER_BOX:
114+ case PADDING_BOX:
115+ shape = new Rectangle2D.Double(x, y, width, height);
116+ break;
117+ case CONTENT_BOX:
118+ shape = new Rectangle2D.Double(x + ppLeft, y + ppTop, width - ppLeft - ppRight,
119+ height - ppTop - ppBottom);
120+ break;
121+ default:
122+ throw new IllegalStateException(Byte.toString(this.backgroundClip));
123+ }
84124 } else {
85- shape = BorderRenderer.SHARED_INSTANCE.getBorderShape(border, x, y, width, height);
125+ switch (this.backgroundClip) {
126+ case BORDER_BOX:
127+ shape = BorderRenderer.SHARED_INSTANCE.getBorderShape(border, x, y, width, height);
128+ break;
129+ case PADDING_BOX:
130+ shape = new Rectangle2D.Double(x + pbLeft, y + pbTop, width - pbLeft - pbRight,
131+ height - pbTop - pbBottom);
132+ break;
133+ case CONTENT_BOX:
134+ shape = new Rectangle2D.Double(x + pbLeft + ppLeft, y + pbTop + ppTop, width - pbLeft - pbRight- ppLeft - ppRight,
135+ height - pbTop - pbBottom - ppTop - ppBottom);
136+ break;
137+ default:
138+ throw new IllegalStateException(Byte.toString(this.backgroundClip));
139+ }
86140 }
87141 /* NoAndroid end */
88142 /* Android begin *//*
@@ -92,12 +146,11 @@
92146 * BorderRenderer.SHARED_INSTANCE.getBorderXRectF (border, x, y, width, height);
93147 * }
94148 *//* Android end */
149+ gc.begin();
95150 if (this.backgroundColor != null) {
96151 // 背景色
97- gc.begin();
98152 gc.setFillPaint(this.backgroundColor);
99153 gc.fill(shape);
100- gc.end();
101154 }
102155 if (this.backgroundImage != null) {
103156 // 背景画像描画
@@ -168,9 +221,7 @@
168221 double sy = imageHeight / this.backgroundImage.image.getHeight();
169222
170223 // 描画
171- gc.begin();
172224 gc.clip(shape);
173-
174225 switch (this.backgroundImage.repeat) {
175226 case BackgroundImage.REPEAT_NO: {
176227 // 繰り返しなし
@@ -235,8 +286,8 @@
235286 default:
236287 throw new IllegalStateException();
237288 }
238- gc.end();
239289 }
290+ gc.end();
240291 }
241292 }
242293
--- copper/trunk/homare/src/main/java/jp/cssj/homare/style/builder/PageGenerator.java (revision 1621)
+++ copper/trunk/homare/src/main/java/jp/cssj/homare/style/builder/PageGenerator.java (revision 1622)
@@ -2,6 +2,7 @@
22
33 import jp.cssj.homare.style.box.impl.PageBox;
44 import jp.cssj.homare.style.box.params.Types;
5+import jp.cssj.homare.ua.UserAgent;
56 import jp.cssj.sakae.gc.GraphicsException;
67
78 public interface PageGenerator {
@@ -8,6 +9,8 @@
89 public static final byte NONE = Types.PAGE_BREAK_AUTO;
910 public static final byte VERSO = Types.PAGE_BREAK_VERSO;
1011 public static final byte RECTO = Types.PAGE_BREAK_RECTO;
12+
13+ public UserAgent getUserAgent();
1114
1215 public byte getPageSide();
1316
--- copper/trunk/homare/src/main/java/jp/cssj/homare/style/draw/BackgroundBorderDrawable.java (revision 1621)
+++ copper/trunk/homare/src/main/java/jp/cssj/homare/style/draw/BackgroundBorderDrawable.java (revision 1622)
@@ -5,6 +5,7 @@
55
66 import jp.cssj.homare.style.box.impl.PageBox;
77 import jp.cssj.homare.style.box.params.Background;
8+import jp.cssj.homare.style.box.params.Insets;
89 import jp.cssj.homare.style.box.params.RectBorder;
910 import jp.cssj.sakae.gc.GC;
1011 import jp.cssj.sakae.gc.GraphicsException;
@@ -12,22 +13,20 @@
1213 public class BackgroundBorderDrawable extends AbstractDrawable {
1314 protected final Background background;
1415 protected final RectBorder border;
16+ protected final Insets padding;
1517 protected final double width, height;
1618
1719 public BackgroundBorderDrawable(PageBox pageBox, Shape clip, float opacity, AffineTransform transform,
18- Background background, RectBorder border, double width, double height) {
20+ Background background, RectBorder border, Insets padding, double width, double height) {
1921 super(pageBox, clip, opacity, transform);
2022 this.background = background;
2123 this.border = border;
2224 this.width = width;
2325 this.height = height;
26+ this.padding = padding;
2427 }
2528
2629 public void innerDraw(GC gc, double x, double y) throws GraphicsException {
27- double pbLeft = this.border.getLeft().width;
28- double pbTop = this.border.getTop().width;
29- double pbRight = this.border.getRight().width;
30- double pbBottom = this.border.getBottom().width;
31- this.background.draw(gc, x, y, this.width, this.height, pbLeft, pbTop, pbRight, pbBottom, this.border);
30+ this.background.draw(gc, x, y, this.width, this.height, this.border, this.padding);
3231 }
3332 }
--- copper/trunk/homare/src/main/java/jp/cssj/homare/style/draw/BackgroundDrawable.java (revision 1621)
+++ copper/trunk/homare/src/main/java/jp/cssj/homare/style/draw/BackgroundDrawable.java (revision 1622)
@@ -21,6 +21,6 @@
2121 }
2222
2323 public void innerDraw(GC gc, double x, double y) throws GraphicsException {
24- this.background.draw(gc, x, y, this.width, this.height, 0, 0, 0, 0, null);
24+ this.background.draw(gc, x, y, this.width, this.height, null, null);
2525 }
2626 }
--- copper/trunk/homare/src/main/java/jp/cssj/homare/style/part/AbsoluteRectFrame.java (revision 1621)
+++ copper/trunk/homare/src/main/java/jp/cssj/homare/style/part/AbsoluteRectFrame.java (revision 1622)
@@ -73,11 +73,7 @@
7373 y += this.margin.top;
7474 width -= this.margin.getFrameWidth();
7575 height -= this.margin.getFrameHeight();
76- double pbLeft = this.frame.border.getLeft().width;
77- double pbTop = this.frame.border.getTop().width;
78- double pbRight = this.frame.border.getRight().width;
79- double pbBottom = this.frame.border.getBottom().width;
80- this.frame.background.draw(gc, x, y, width, height, pbLeft, pbTop, pbRight, pbBottom, this.frame.border);
76+ this.frame.background.draw(gc, x, y, width, height, this.frame.border, this.frame.padding);
8177 this.frame.border.draw(gc, x, y, width, height);
8278 }
8379
--- copper/trunk/homare/src/main/java/jp/cssj/homare/ua/props/UAProps.java (revision 1621)
+++ copper/trunk/homare/src/main/java/jp/cssj/homare/ua/props/UAProps.java (revision 1622)
@@ -31,6 +31,12 @@
3131 null);
3232
3333 /**
34+ * Normalize text by NFC mode.
35+ */
36+ public static final BooleanPropManager INPUT_NORMALIZE_TEXT = new BooleanPropManager("input.normalize-text",
37+ false);
38+
39+ /**
3440 * デフォルトのエンコーディングです。
3541 */
3642 public static final StringPropManager INPUT_DEFAULT_ENCODING = new StringPropManager("input.default-encoding",
--- copper/trunk/sakae/sakae-pdf/src/main/java/jp/cssj/sakae/pdf/font/FontManagerImpl.java (revision 1621)
+++ copper/trunk/sakae/sakae-pdf/src/main/java/jp/cssj/sakae/pdf/font/FontManagerImpl.java (revision 1622)
@@ -19,6 +19,7 @@
1919 import jp.cssj.sakae.gc.text.Glypher;
2020 import jp.cssj.sakae.gc.text.Quad;
2121 import jp.cssj.sakae.pdf.font.cid.missing.MissingCIDFontSource;
22+import jp.cssj.sakae.pdf.font.cid.missing.SpaceCIDFontSource;
2223
2324 /**
2425 * Implementation of FontManager for PDF.
@@ -59,7 +60,7 @@
5960 if (flm != null) {
6061 return flm;
6162 }
62- int count = 1;
63+ int count = 2;
6364 FontSource[] fonts1;
6465 if (this.localdb != null) {
6566 fonts1 = this.localdb.lookup(fontStyle);
@@ -82,8 +83,10 @@
8283 }
8384
8485 if (fontStyle.getDirection() == FontStyle.DIRECTION_TB) {
86+ fms[fms.length - 2] = new FontMetricsImpl(this.fontStore, SpaceCIDFontSource.INSTANCES_TB, fontStyle);
8587 fms[fms.length - 1] = new FontMetricsImpl(this.fontStore, MissingCIDFontSource.INSTANCES_TB, fontStyle);
8688 } else {
89+ fms[fms.length - 2] = new FontMetricsImpl(this.fontStore, SpaceCIDFontSource.INSTANCES_LTR, fontStyle);
8790 fms[fms.length - 1] = new FontMetricsImpl(this.fontStore, MissingCIDFontSource.INSTANCES_LTR, fontStyle);
8891 }
8992 flm = new FontListMetrics(fms);
@@ -110,7 +113,7 @@
110113
111114 private int fontBound = 0;
112115
113- private boolean zwj = false; // ZWJ(u200D)およびそれに続く文字はフォントを変えない
116+ private boolean zw = false; // ZWS(u200B), ZWJ(u200D)およびそれに続く文字はフォントを変えない
114117
115118 private FontStyle fontStyle;
116119
@@ -138,7 +141,7 @@
138141 if (!this.outOfRun) {
139142 this.glyph();
140143 this.endRun();
141- this.zwj = false;
144+ this.zw = false;
142145 }
143146 }
144147
@@ -166,14 +169,14 @@
166169
167170 // ランの範囲を作成
168171 if (this.fontMetrics.canDisplay(cc)) {
169- if (cc == 0x200D) {
170- this.zwj = true;
172+ if (cc >= 0x200B && cc <= 0x200D) {
173+ this.zw = true;
171174 }
172175 } else {
173176 this.glyphBreak();
174177 this.initFont();
175178 }
176- if (!this.zwj) {
179+ if (!this.zw) {
177180 // 優先順位の高いフォントに切り替える
178181 for (int j = 0; j < this.fontBound; ++j) {
179182 FontMetricsImpl metrics = (FontMetricsImpl) this.fontListMetrics.getFontMetrics(j);
@@ -221,7 +224,7 @@
221224 this.ch[1] = ls;
222225 this.len = 2;
223226 }
224- this.zwj = (cc == 0x200D);
227+ this.zw = (cc >= 0x200B && cc <= 0x200D);
225228 }
226229
227230 this.pgid = this.gid;
@@ -247,7 +250,7 @@
247250 private void initFont() {
248251 this.fontBound = this.fontListMetrics.getLength();
249252 this.fontMetrics = (FontMetricsImpl) this.fontListMetrics.getFontMetrics(this.fontBound - 1);
250- this.zwj = false;
253+ this.zw = false;
251254 }
252255
253256 public void flush() {
--- copper/trunk/sakae/sakae-pdf/src/main/java/jp/cssj/sakae/pdf/font/cid/missing/MissingCIDFont.java (revision 1621)
+++ copper/trunk/sakae/sakae-pdf/src/main/java/jp/cssj/sakae/pdf/font/cid/missing/MissingCIDFont.java (revision 1622)
@@ -76,37 +76,6 @@
7676
7777 public short getAdvance(int gid) {
7878 int c = this.unicodes.get(gid);
79- switch (c) {
80- // 制御コード
81- case 0x0000:
82- case 0x000B:
83- case 0x001C:
84- case 0x001D:
85- case 0x001E:
86- case 0x001F:
87- // ゼロ幅空白
88- case 0x200B:
89- case 0x200C:
90- case 0x200D:
91- case 0x200E:
92- case 0x200F:
93- case 0x202A:
94- case 0x202B:
95- case 0x202C:
96- case 0x202D:
97- case 0x202E:
98- case 0x2060:
99- case 0xFEFF:
100- return (short) 0;
101- // スペース文字
102- case 0x007F:
103- case 0x0020:
104- case 0x00A0:
105- case 0x2028:
106- case 0x2029:
107- case 0x202F:
108- return (short) 500;
109- }
11079 return (short) (c <= 0xFFFF ? 1000 : 1400);
11180 }
11281
--- copper/trunk/sakae/sakae-pdf/src/main/java/jp/cssj/sakae/pdf/font/cid/missing/MissingCIDFontSource.java (revision 1621)
+++ copper/trunk/sakae/sakae-pdf/src/main/java/jp/cssj/sakae/pdf/font/cid/missing/MissingCIDFontSource.java (revision 1622)
@@ -27,7 +27,7 @@
2727
2828 private final byte direction;
2929
30- private MissingCIDFontSource(byte direction) {
30+ MissingCIDFontSource(byte direction) {
3131 this.direction = direction;
3232 }
3333
@@ -80,7 +80,7 @@
8080 }
8181
8282 public boolean canDisplay(int c) {
83- return true;
83+ return !SpaceCIDFontSource.INSTANCES_LTR.canDisplay(c);
8484 }
8585
8686 public Panose getPanose() {
--- copper/trunk/sakae/sakae-pdf/src/main/java/jp/cssj/sakae/pdf/font/cid/missing/SpaceCIDFont.java (nonexistent)
+++ copper/trunk/sakae/sakae-pdf/src/main/java/jp/cssj/sakae/pdf/font/cid/missing/SpaceCIDFont.java (revision 1622)
@@ -0,0 +1,39 @@
1+package jp.cssj.sakae.pdf.font.cid.missing;
2+
3+import java.io.IOException;
4+
5+import jp.cssj.sakae.gc.GC;
6+import jp.cssj.sakae.gc.GraphicsException;
7+import jp.cssj.sakae.gc.text.Text;
8+import jp.cssj.sakae.pdf.ObjectRef;
9+
10+class SpaceCIDFont extends MissingCIDFont {
11+ private static final long serialVersionUID = 1L;
12+
13+ public SpaceCIDFont(MissingCIDFontSource source, String name, ObjectRef fontRef) {
14+ super(source, name, fontRef);
15+ }
16+
17+ public short getAdvance(int gid) {
18+ int c = this.unicodes.get(gid);
19+ switch (c) {
20+ // スペース文字
21+ case 0x007F:
22+ case 0x0020:
23+ case 0x00A0:
24+ case 0x2028:
25+ case 0x2029:
26+ case 0x202F:
27+ return (short) 500;
28+ }
29+ return (short)0;
30+ }
31+
32+ public short getWidth(int gid) {
33+ return (short)0;
34+ }
35+
36+ public void drawTo(GC gc, Text text) throws IOException, GraphicsException {
37+ // ignore
38+ }
39+}
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
--- copper/trunk/sakae/sakae-pdf/src/main/java/jp/cssj/sakae/pdf/font/cid/missing/SpaceCIDFontSource.java (nonexistent)
+++ copper/trunk/sakae/sakae-pdf/src/main/java/jp/cssj/sakae/pdf/font/cid/missing/SpaceCIDFontSource.java (revision 1622)
@@ -0,0 +1,64 @@
1+package jp.cssj.sakae.pdf.font.cid.missing;
2+
3+import jp.cssj.sakae.gc.font.FontStyle;
4+import jp.cssj.sakae.pdf.ObjectRef;
5+import jp.cssj.sakae.pdf.font.PdfFont;
6+
7+/**
8+ *
9+ * @author MIYABE Tatsuhiko
10+ * @version $Id: GenericType0FontFace.java,v 1.2 2005/06/06 04:42:24 harumanx
11+ * Exp $
12+ */
13+public class SpaceCIDFontSource extends MissingCIDFontSource {
14+ private static final long serialVersionUID = 1L;
15+
16+ public static final SpaceCIDFontSource INSTANCES_LTR = new SpaceCIDFontSource(FontStyle.DIRECTION_LTR);
17+ public static final SpaceCIDFontSource INSTANCES_TB = new SpaceCIDFontSource(FontStyle.DIRECTION_TB);
18+
19+ SpaceCIDFontSource(byte direction) {
20+ super(direction);
21+ }
22+
23+ public String getFontName() {
24+ return "SPACE";
25+ }
26+
27+ public boolean canDisplay(int c) {
28+ switch (c) {
29+ // 制御コード
30+ case 0x0000:
31+ case 0x000B:
32+ case 0x001C:
33+ case 0x001D:
34+ case 0x001E:
35+ case 0x001F:
36+ // ゼロ幅空白
37+ case 0x200B:
38+ case 0x200C:
39+ case 0x200D:
40+ case 0x200E:
41+ case 0x200F:
42+ case 0x202A:
43+ case 0x202B:
44+ case 0x202C:
45+ case 0x202D:
46+ case 0x202E:
47+ case 0x2060:
48+ case 0xFEFF:
49+ // スペース文字
50+ case 0x007F:
51+ case 0x0020:
52+ case 0x00A0:
53+ case 0x2028:
54+ case 0x2029:
55+ case 0x202F:
56+ return true;
57+ }
58+ return false;
59+ }
60+
61+ public PdfFont createFont(String name, ObjectRef fontRef) {
62+ return new SpaceCIDFont(this, name, fontRef);
63+ }
64+}
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
--- copper/trunk/sakae/sakae-pdf/src/main/java/jp/cssj/sakae/pdf/impl/ImageFlow.java (revision 1621)
+++ copper/trunk/sakae/sakae-pdf/src/main/java/jp/cssj/sakae/pdf/impl/ImageFlow.java (revision 1622)
@@ -110,20 +110,38 @@
110110 PdfImage pdfImage;
111111 ImageReader ir;
112112 if (imageIn != null) {
113+ CMYKJPEGImageReader cir = null;
113114 Iterator<ImageReader> iri = ImageIO.getImageReaders(imageIn);
114115 for (;;) {
115116 if (iri != null && iri.hasNext()) {
116117 ir = iri.next();
117118 ir.setInput(imageIn);
118- Iterator<ImageTypeSpecifier> iti = ir.getImageTypes(0);
119- if (iti != null && iti.hasNext()) {
120- break;
119+ try {
120+ Iterator<ImageTypeSpecifier> iti = ir.getImageTypes(0);
121+ if (iti != null && iti.hasNext()) {
122+ imageIn.seek(0);
123+ if (ir instanceof CMYKJPEGImageReader) {
124+ cir = (CMYKJPEGImageReader)ir;
125+ continue;
126+ }
127+ break;
128+ }
129+ } catch (IOException e) {
130+ // ignore
121131 }
122132 ir.dispose();
133+ imageIn.seek(0);
123134 } else {
124- throw new IOException("画像ファイル内に読み込み可能な画像がありません:" + String.valueOf(iri));
135+ if (cir == null) {
136+ throw new IOException("画像ファイル内に読み込み可能な画像がありません:" + String.valueOf(iri));
137+ }
138+ ir = cir;
139+ break;
125140 }
126141 }
142+ if (cir != null) {
143+ cir.dispose();
144+ }
127145 } else {
128146 ir = null;
129147 }
Show on old repository browser