1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package net.sourceforge.jeuclid.elements;
20
21 import java.awt.Color;
22 import java.awt.Font;
23 import java.awt.FontMetrics;
24 import java.awt.Graphics2D;
25 import java.awt.geom.Line2D;
26 import java.awt.geom.Rectangle2D;
27 import java.util.HashMap;
28 import java.util.HashSet;
29 import java.util.Map;
30 import java.util.Set;
31
32 import net.sourceforge.jeuclid.MathBase;
33 import net.sourceforge.jeuclid.ParameterKey;
34 import net.sourceforge.jeuclid.dom.AbstractChangeTrackingElement;
35 import net.sourceforge.jeuclid.dom.PartialTextImpl;
36 import net.sourceforge.jeuclid.elements.generic.MathImpl;
37 import net.sourceforge.jeuclid.elements.presentation.general.Mrow;
38 import net.sourceforge.jeuclid.elements.presentation.table.Mtable;
39 import net.sourceforge.jeuclid.elements.presentation.table.Mtr;
40 import net.sourceforge.jeuclid.elements.presentation.token.Mo;
41 import net.sourceforge.jeuclid.elements.presentation.token.Mtext;
42 import net.sourceforge.jeuclid.elements.support.attributes.AttributeMap;
43 import net.sourceforge.jeuclid.elements.support.attributes.AttributesHelper;
44 import net.sourceforge.jeuclid.elements.support.attributes.MathVariant;
45 import net.sourceforge.jeuclid.elements.support.text.CharConverter;
46
47 import org.apache.commons.logging.Log;
48 import org.apache.commons.logging.LogFactory;
49 import org.w3c.dom.Node;
50 import org.w3c.dom.Text;
51 import org.w3c.dom.mathml.MathMLElement;
52 import org.w3c.dom.mathml.MathMLMathElement;
53 import org.w3c.dom.mathml.MathMLNodeList;
54
55
56
57
58
59
60
61
62
63
64 public abstract class AbstractJEuclidElement extends
65
66 AbstractChangeTrackingElement implements JEuclidElement {
67
68
69 public static final String ATTR_MATHVARIANT = "mathvariant";
70
71
72 public static final String ATTR_MATHCOLOR = "mathcolor";
73
74
75 public static final String ATTR_MATHSIZE = "mathsize";
76
77
78 public static final String ATTR_DEPRECATED_FONTFAMILY = "fontfamily";
79
80
81 public static final String ATTR_DEPRECATED_FONTSTYLE = "fontstyle";
82
83
84 public static final String ATTR_DEPRECATED_FONTWEIGHT = "fontweight";
85
86
87 public static final String ATTR_DEPRECATED_FONTSIZE = "fontsize";
88
89
90 public static final String ATTR_DEPRECATED_COLOR = "color";
91
92
93 public static final String ATTR_DEPRECATED_BACKGROUND = "background";
94
95
96 public static final String ATTR_CLASS = "class";
97
98
99 public static final String ATTR_STYLE = "style";
100
101
102 public static final String ATTR_ID = "id";
103
104
105 public static final String ATTR_HREF = "xlink:href";
106
107
108 public static final String ATTR_XREF = "xref";
109
110
111 public static final String ATTR_MATHBACKGROUND = "mathbackground";
112
113
114 public static final String ALIGN_TOP = "top";
115
116
117 public static final String ALIGN_BOTTOM = "bottom";
118
119
120 public static final String ALIGN_CENTER = "center";
121
122
123 public static final String ALIGN_BASELINE = "baseline";
124
125
126 public static final String ALIGN_AXIS = "axis";
127
128
129 public static final String ALIGN_LEFT = "left";
130
131
132 public static final String ALIGN_RIGHT = "right";
133
134
135
136
137
138 public static final int TRIVIAL_SPACE_MAX = 0x20;
139
140
141
142
143 public static final String URI = "http://www.w3.org/1998/Math/MathML";
144
145 private static final float MIDDLE_SHIFT = 0.38f;
146
147 private static final float DEFAULT_SCIPTSIZEMULTIPLIER = 0.71f;
148
149
150
151
152 private static final Log LOGGER = LogFactory
153 .getLog(AbstractJEuclidElement.class);
154
155 private static final Set<String> DEPRECATED_ATTRIBUTES = new HashSet<String>();
156
157
158
159
160
161 private MathBase mbase;
162
163
164
165
166 private boolean calculatingSize;
167
168
169
170
171 private float calculatedHeight = -1;
172
173
174
175
176 private float calculatedWidth = -1;
177
178
179
180
181 private float calculatedAscentHeight = -1;
182
183
184
185
186 private float calculatedDescentHeight = -1;
187
188
189
190
191 private float calculatedStretchHeight = -1;
192
193
194
195
196 private float calculatedStretchAscentHeight = -1;
197
198
199
200
201 private float calculatedStretchDescentHeight = -1;
202
203 private float lastPaintedX = -1;
204
205 private float lastPaintedY = -1;
206
207
208
209
210 private JEuclidElement fakeParent;
211
212 private final Map<String, String> defaultMathAttributes = new HashMap<String, String>();
213
214
215
216
217 private float mscriptsizemultiplier = AbstractJEuclidElement.DEFAULT_SCIPTSIZEMULTIPLIER;
218
219
220
221
222
223
224
225 private float globalLineCorrecter;
226
227
228
229
230
231
232
233
234 public AbstractJEuclidElement(final MathBase base) {
235 this.setMathBase(base);
236 }
237
238
239
240
241 protected void recalculateSize() {
242 this.calculatedHeight = -1;
243 this.calculatedAscentHeight = -1;
244 this.calculatedDescentHeight = -1;
245 this.calculatedStretchHeight = -1;
246 this.calculatedStretchAscentHeight = -1;
247 this.calculatedStretchDescentHeight = -1;
248 this.calculatedWidth = -1;
249 }
250
251
252 @Override
253 protected void changeHook() {
254 super.changeHook();
255 this.recalculateSize();
256 }
257
258
259
260
261
262
263 public float getFontsizeInPoint() {
264 final float scriptMultiplier = (float) Math.pow(this
265 .getScriptSizeMultiplier(), this.getAbsoluteScriptLevel());
266 float size = this.getMathsizeInPoint() * scriptMultiplier;
267
268
269
270 final float minSize = this.mbase.getFontSize() * 0.66f;
271 if (size < minSize) {
272 size = minSize;
273 }
274 return size;
275 }
276
277
278
279
280
281
282
283 public Font getFont() {
284 final String content = this.getText();
285 final char aChar;
286 if (content.length() > 0) {
287 aChar = content.charAt(0);
288 } else {
289 aChar = 'A';
290 }
291 return this.getMathvariantAsVariant().createFont(
292 this.getFontsizeInPoint(), aChar, this.mbase);
293
294 }
295
296
297 public MathVariant getMathvariantAsVariant() {
298 final String mv = this.getMathvariant();
299 MathVariant variant = null;
300 if (mv != null) {
301 variant = MathVariant.stringToMathVariant(mv);
302 }
303 if (variant == null) {
304
305 final JEuclidElement parent = this.getParent();
306 if (parent != null) {
307 variant = parent.getMathvariantAsVariant();
308 } else {
309
310 variant = MathVariant.NORMAL;
311 }
312 }
313 return variant;
314 }
315
316
317
318
319
320
321
322
323 protected int getAbsoluteScriptLevel() {
324 return this.getInheritedScriptlevel();
325 }
326
327
328
329
330
331
332 protected int getInheritedScriptlevel() {
333 final JEuclidElement parent = this.getParent();
334 if (parent == null) {
335 return 0;
336 } else {
337 return parent.getScriptlevelForChild(this);
338 }
339 }
340
341
342 public int getScriptlevelForChild(final JEuclidElement child) {
343 return this.getAbsoluteScriptLevel();
344 }
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450 public final void addMathElement(final MathMLElement child) {
451 if (child != null) {
452 this.appendChild(child);
453 if (child instanceof AbstractJEuclidElement) {
454 ((AbstractJEuclidElement) child).setMathBase(this
455 .getMathBase());
456 }
457 }
458 }
459
460
461 public JEuclidElement getMathElement(final int index) {
462 if (index >= 0 && index < this.getMathElementCount()) {
463 final org.w3c.dom.NodeList childList = this.getChildNodes();
464 for (int i = 0, elementIndex = 0; i < childList.getLength(); i++) {
465 final Node child = childList.item(i);
466 if (child instanceof JEuclidElement) {
467 if (elementIndex == index) {
468 return (JEuclidElement) child;
469 }
470 elementIndex++;
471 }
472 }
473 }
474 return null;
475 }
476
477
478 public void setMathElement(final int index, final MathMLElement newElement) {
479 final org.w3c.dom.NodeList childList = this.getChildNodes();
480 while (childList.getLength() < index) {
481 this.addMathElement(new Mtext(this.mbase));
482 }
483 if (childList.getLength() == index) {
484 this.addMathElement(newElement);
485 } else {
486 this.replaceChild(newElement, childList.item(index));
487 }
488 }
489
490
491 public int getIndexOfMathElement(final JEuclidElement element) {
492 final org.w3c.dom.NodeList childList = this.getChildNodes();
493 for (int i = 0; i < childList.getLength(); i++) {
494 if (childList.item(i).equals(element)) {
495 return i;
496 }
497 }
498 return -1;
499 }
500
501
502 public int getMathElementCount() {
503 final org.w3c.dom.NodeList childList = this.getChildNodes();
504 int elementIndex = 0;
505 for (int i = 0; i < childList.getLength(); i++) {
506 final Node child = childList.item(i);
507 if (child instanceof JEuclidElement) {
508 elementIndex++;
509 }
510 }
511 return elementIndex;
512 }
513
514
515
516
517
518
519
520 public void addText(final String text) {
521 Node textNode = this.getLastChild();
522 if (!(textNode instanceof Text)) {
523 textNode = new PartialTextImpl("");
524 this.appendChild(textNode);
525 }
526
527 final StringBuilder newText = new StringBuilder();
528 if (this.getTextContent() != null) {
529 newText.append(textNode.getTextContent());
530 }
531
532
533 if (text != null) {
534 newText.append(text.trim());
535 }
536
537 for (int i = 0; i < newText.length() - 1; i++) {
538 if (newText.charAt(i) <= AbstractJEuclidElement.TRIVIAL_SPACE_MAX
539 && newText.charAt(i + 1) <= AbstractJEuclidElement.TRIVIAL_SPACE_MAX) {
540 newText.deleteCharAt(i);
541
542
543 i--;
544
545 }
546 }
547
548 final String toSet = CharConverter.convertEarly(newText.toString());
549 if (toSet.length() > 0) {
550 textNode.setTextContent(toSet);
551 } else {
552 this.removeChild(textNode);
553 }
554
555 }
556
557
558
559
560
561
562 public String getText() {
563 final String theText = this.getTextContent();
564 if (theText == null) {
565 return "";
566 } else {
567 return theText;
568 }
569 }
570
571
572
573
574
575
576
577
578 public void setMathBase(final MathBase base) {
579 this.mbase = base;
580 final org.w3c.dom.NodeList childList = this.getChildNodes();
581 for (int i = 0; i < childList.getLength(); i++) {
582 final Node node = childList.item(i);
583 if (node instanceof AbstractJEuclidElement) {
584 ((AbstractJEuclidElement) node).setMathBase(base);
585 }
586 }
587 }
588
589
590 public MathBase getMathBase() {
591 return this.mbase;
592 }
593
594
595 public void setFakeParent(final JEuclidElement parent) {
596 this.fakeParent = parent;
597 }
598
599
600 public JEuclidElement getParent() {
601 final Node parentNode = this.getParentNode();
602 JEuclidElement theParent = null;
603 if (parentNode instanceof JEuclidElement) {
604 theParent = (JEuclidElement) this.getParentNode();
605 }
606 if (theParent == null) {
607 return this.fakeParent;
608 } else {
609 return theParent;
610 }
611 }
612
613
614
615
616
617
618
619 public void setMathvariant(final String mathvariant) {
620 this.setAttribute(AbstractJEuclidElement.ATTR_MATHVARIANT,
621 mathvariant);
622 }
623
624
625
626
627
628
629 public String getMathvariant() {
630
631 return this.getMathAttribute(AbstractJEuclidElement.ATTR_MATHVARIANT);
632 }
633
634
635
636
637
638
639 public float getScriptSizeMultiplier() {
640 return this.mscriptsizemultiplier;
641 }
642
643
644
645
646
647
648
649 public void setScriptSizeMultiplier(final float scriptsizemultiplier) {
650 this.mscriptsizemultiplier = scriptsizemultiplier;
651 }
652
653
654
655
656
657
658
659
660 public FontMetrics getFontMetrics(final Graphics2D g) {
661 return g.getFontMetrics(this.getFont());
662 }
663
664
665
666
667
668
669
670 public void setMathcolor(final String mathcolor) {
671 this.setAttribute(AbstractJEuclidElement.ATTR_MATHCOLOR, mathcolor);
672 }
673
674
675
676
677
678
679 public String getMathcolor() {
680 String color;
681 color = this.getMathAttribute(AbstractJEuclidElement.ATTR_MATHCOLOR);
682 if (color == null) {
683 color = this
684 .getMathAttribute(AbstractJEuclidElement.ATTR_DEPRECATED_COLOR);
685 }
686 return color;
687 }
688
689
690
691
692
693
694 public String getMathsize() {
695 String size;
696 size = this.getMathAttribute(AbstractJEuclidElement.ATTR_MATHSIZE);
697 if (size == null) {
698 size = this
699 .getMathAttribute(AbstractJEuclidElement.ATTR_DEPRECATED_FONTSIZE);
700 }
701 return size;
702
703 }
704
705
706
707
708
709
710
711 public void setMathsize(final String mathsize) {
712 this.setAttribute(AbstractJEuclidElement.ATTR_MATHSIZE, mathsize);
713 }
714
715
716 public float getMathsizeInPoint() {
717
718 final String msize = this.getMathsize();
719
720 JEuclidNode relativeToElement = null;
721 if (this.getParent() != null) {
722 relativeToElement = this.getParent();
723 } else {
724 relativeToElement = this.mbase.getRootElement();
725 }
726 if (msize == null) {
727 return relativeToElement.getMathsizeInPoint();
728 }
729 return AttributesHelper.convertSizeToPt(msize, relativeToElement,
730 AttributesHelper.PT);
731 }
732
733
734
735
736
737
738
739
740
741
742
743 protected void setDefaultMathAttribute(final String key,
744 final String value) {
745 this.defaultMathAttributes.put(key, value);
746 }
747
748
749
750
751
752
753
754
755 protected String getMathAttribute(final String attrName) {
756 String attrValue;
757 attrValue = this.getAttributeNS(AbstractJEuclidElement.URI, attrName);
758 if (attrValue == null) {
759 attrValue = this.getAttribute(attrName);
760 }
761 if (attrValue == null) {
762 attrValue = this.defaultMathAttributes.get(attrName);
763 }
764 return attrValue;
765 }
766
767
768
769
770
771
772 public String getMathbackground() {
773 String color;
774 color = this
775 .getMathAttribute(AbstractJEuclidElement.ATTR_MATHBACKGROUND);
776 if (color == null) {
777 color = this
778 .getMathAttribute(AbstractJEuclidElement.ATTR_DEPRECATED_BACKGROUND);
779 }
780 return color;
781 }
782
783
784
785
786
787
788
789 public void setMathbackground(final String mathbackground) {
790 this.setAttribute(AbstractJEuclidElement.ATTR_MATHBACKGROUND,
791 mathbackground);
792 }
793
794
795 public Color getForegroundColor() {
796 final String colorString = this.getMathcolor();
797 Color theColor;
798 if (colorString == null) {
799 if (this.getParent() != null) {
800 theColor = this.getParent().getForegroundColor();
801 } else {
802 theColor = AttributesHelper.stringToColor(this.mbase
803 .getParams().get(ParameterKey.ForegroundColor),
804 Color.BLACK);
805 }
806 } else {
807 theColor = AttributesHelper.stringToColor(colorString,
808 Color.BLACK);
809 }
810 return theColor;
811 }
812
813
814 public Color getBackgroundColor() {
815 final String colorString = this.getMathbackground();
816 final Color theColor;
817 if (colorString == null) {
818 if (this.getParent() != null) {
819
820
821 theColor = null;
822 } else {
823 theColor = AttributesHelper.stringToColor(this.mbase
824 .getParams().get(ParameterKey.BackgroundColor), null);
825 }
826 } else {
827 theColor = AttributesHelper.stringToColor(colorString, null);
828 }
829 return theColor;
830 }
831
832
833
834
835
836
837
838
839
840
841
842 public void debug(final Graphics2D g, final float posX, final float posY) {
843 g.setColor(Color.blue);
844 g.draw(new Line2D.Float(posX, posY - this.getAscentHeight(g), posX
845 + this.getWidth(g), posY - this.getAscentHeight(g)));
846 g.draw(new Line2D.Float(posX + this.getWidth(g), posY
847 - this.getAscentHeight(g), posX + this.getWidth(g), posY
848 + this.getDescentHeight(g)));
849 g.draw(new Line2D.Float(posX, posY + this.getDescentHeight(g), posX
850 + this.getWidth(g), posY + this.getDescentHeight(g)));
851 g.draw(new Line2D.Float(posX, posY - this.getAscentHeight(g), posX,
852 posY + this.getDescentHeight(g)));
853 g.setColor(Color.red);
854 g.draw(new Line2D.Float(posX, posY, posX + this.getWidth(g), posY));
855 g.setColor(Color.black);
856 }
857
858
859 public void setGlobalLineCorrector(final float corrector) {
860 if (this.getParent() == null) {
861 return;
862 }
863
864
865 if (this instanceof Mtr || this instanceof Mrow
866 && this.getParent() instanceof Mtable
867 || this.getParent() instanceof MathImpl) {
868 if (this.globalLineCorrecter < corrector) {
869 this.globalLineCorrecter = corrector;
870 }
871 } else {
872 this.getParent().setGlobalLineCorrector(corrector);
873 }
874 }
875
876
877 public float getGlobalLineCorrector() {
878 final float retVal;
879 if (this.getParent() == null) {
880 retVal = 0;
881 } else
882
883
884
885 if (this instanceof Mtr || this instanceof Mrow
886 && this.getParent() instanceof Mtable
887 || this.getParent() instanceof MathImpl) {
888 retVal = this.globalLineCorrecter;
889 } else {
890 retVal = this.getParent().getGlobalLineCorrector();
891 }
892 return retVal;
893 }
894
895
896 public float getWidth(final Graphics2D g) {
897 if (this.calculatedWidth < 0) {
898 this.calculatedWidth = this.calculateWidth(g);
899 }
900 return this.calculatedWidth;
901 }
902
903
904
905
906
907
908
909
910 public abstract float calculateWidth(Graphics2D g);
911
912
913 public float getHeight(final Graphics2D g) {
914 if (this.calculatingSize || this.getParent() != null
915 && this.getParent().isCalculatingSize()) {
916 if (this.calculatedStretchHeight < 0) {
917 this.calculatedStretchHeight = this.calculateHeight(g);
918 }
919 return this.calculatedStretchHeight;
920 } else {
921 if (this.calculatedHeight < 0) {
922 this.calculatedHeight = this.calculateHeight(g);
923 }
924 return this.calculatedHeight;
925 }
926 }
927
928
929
930
931
932
933
934
935 public float calculateHeight(final Graphics2D g) {
936 return this.getAscentHeight(g) + this.getDescentHeight(g);
937 }
938
939
940 public float getAscentHeight(final Graphics2D g) {
941 if (this.calculatingSize || this.getParent() != null
942 && this.getParent().isCalculatingSize()) {
943 if (this.calculatedStretchAscentHeight < 0) {
944 this.calculatedStretchAscentHeight = this
945 .calculateAscentHeight(g);
946 }
947 return this.calculatedStretchAscentHeight;
948 } else {
949 if (this.calculatedAscentHeight < 0) {
950 this.calculatedAscentHeight = this.calculateAscentHeight(g);
951 }
952 return this.calculatedAscentHeight;
953 }
954 }
955
956
957 public abstract float calculateAscentHeight(Graphics2D g);
958
959
960 public float getDescentHeight(final Graphics2D g) {
961 if (this.calculatingSize || this.getParent() != null
962 && this.getParent().isCalculatingSize()) {
963 if (this.calculatedStretchDescentHeight < 0) {
964 this.calculatedStretchDescentHeight = this
965 .calculateDescentHeight(g);
966 }
967 return this.calculatedStretchDescentHeight;
968 } else {
969 if (this.calculatedDescentHeight < 0) {
970 this.calculatedDescentHeight = this.calculateDescentHeight(g);
971 }
972 return this.calculatedDescentHeight;
973 }
974 }
975
976
977 public abstract float calculateDescentHeight(Graphics2D g);
978
979
980
981
982
983
984
985
986 public float getMiddleShift(final Graphics2D g) {
987 return this.getFontMetrics(g).getAscent()
988 * AbstractJEuclidElement.MIDDLE_SHIFT;
989 }
990
991
992 public void setMathAttributes(final AttributeMap attributes) {
993 final Map<String, String> attrsAsMap = attributes.getAsMap();
994 for (final Map.Entry<String, String> e : attrsAsMap.entrySet()) {
995 final String attrName = e.getKey();
996 if (AbstractJEuclidElement.DEPRECATED_ATTRIBUTES
997 .contains(attrName)) {
998 AbstractJEuclidElement.LOGGER
999 .warn("Deprecated attribute for " + this.getTagName()
1000 + ": " + attrName);
1001 }
1002 this.setAttribute(attrName, e.getValue());
1003 }
1004 this.recalculateSize();
1005 }
1006
1007
1008 public boolean isCalculatingSize() {
1009 return this.calculatingSize;
1010 }
1011
1012
1013 public void setCalculatingSize(final boolean ncalculatingSize) {
1014 this.calculatingSize = ncalculatingSize;
1015 }
1016
1017
1018 public String getClassName() {
1019 return this.getAttribute(AbstractJEuclidElement.ATTR_CLASS);
1020 }
1021
1022
1023 public void setClassName(final String className) {
1024 this.setAttribute(AbstractJEuclidElement.ATTR_CLASS, className);
1025 }
1026
1027
1028 public String getMathElementStyle() {
1029 return this.getAttribute(AbstractJEuclidElement.ATTR_STYLE);
1030 }
1031
1032
1033 public void setMathElementStyle(final String mathElementStyle) {
1034 this
1035 .setAttribute(AbstractJEuclidElement.ATTR_STYLE,
1036 mathElementStyle);
1037 }
1038
1039
1040 public String getId() {
1041 return this.getAttribute(AbstractJEuclidElement.ATTR_ID);
1042 }
1043
1044
1045 public void setId(final String id) {
1046 this.setAttribute(AbstractJEuclidElement.ATTR_ID, id);
1047 }
1048
1049
1050 public String getXref() {
1051 return this.getAttribute(AbstractJEuclidElement.ATTR_XREF);
1052 }
1053
1054
1055 public void setXref(final String xref) {
1056 this.setAttribute(AbstractJEuclidElement.ATTR_XREF, xref);
1057 }
1058
1059
1060 public String getHref() {
1061 return this.getAttribute(AbstractJEuclidElement.ATTR_HREF);
1062 }
1063
1064
1065 public void setHref(final String href) {
1066 this.setAttribute(AbstractJEuclidElement.ATTR_HREF, href);
1067 }
1068
1069
1070 public MathMLMathElement getOwnerMathElement() {
1071 JEuclidElement node = this.getParent();
1072 while (node != null) {
1073 if (node instanceof MathMLMathElement) {
1074 return (MathMLMathElement) node;
1075 }
1076 node = node.getParent();
1077 }
1078 return null;
1079 }
1080
1081
1082 public boolean isChildBlock(final JEuclidElement child) {
1083 final JEuclidElement parent = this.getParent();
1084 if (parent != null) {
1085 return parent.isChildBlock(this);
1086 } else {
1087 return true;
1088 }
1089 }
1090
1091
1092 public boolean hasChildPrescripts(final JEuclidElement child) {
1093 return false;
1094 }
1095
1096
1097 public boolean hasChildPostscripts(final JEuclidElement child) {
1098 return false;
1099 }
1100
1101
1102 public void paint(final Graphics2D g, final float posX, final float posY) {
1103 this.lastPaintedX = posX;
1104 this.lastPaintedY = posY;
1105 if (this.getBackgroundColor() != null) {
1106 g.setColor(this.getBackgroundColor());
1107 final float ascent = (float) Math.ceil(this.getAscentHeight(g));
1108 final float descent = (float) Math.ceil(this.getDescentHeight(g));
1109 g.fill(new Rectangle2D.Float(posX, posY - ascent, (float) Math
1110 .ceil(this.getWidth(g)), ascent + descent));
1111 }
1112
1113 if (this.getMathBase().isDebug()) {
1114 this.debug(g, posX, posY);
1115 }
1116 g.setColor(this.getForegroundColor());
1117 g.setFont(this.getFont());
1118
1119 }
1120
1121
1122 public float getPaintedPosX() {
1123 return this.lastPaintedX;
1124 }
1125
1126
1127 public float getPaintedPosY() {
1128 return this.lastPaintedY;
1129 }
1130
1131
1132
1133
1134
1135
1136 public MathMLNodeList getContents() {
1137 return (MathMLNodeList) this.getChildNodes();
1138 }
1139
1140
1141 public float getXCenter(final Graphics2D g) {
1142 return this.getWidth(g) / 2.0f;
1143 }
1144
1145 {
1146 AbstractJEuclidElement.DEPRECATED_ATTRIBUTES
1147 .add(AbstractJEuclidElement.ATTR_DEPRECATED_COLOR);
1148 AbstractJEuclidElement.DEPRECATED_ATTRIBUTES
1149 .add(AbstractJEuclidElement.ATTR_DEPRECATED_BACKGROUND);
1150 AbstractJEuclidElement.DEPRECATED_ATTRIBUTES
1151 .add(AbstractJEuclidElement.ATTR_DEPRECATED_FONTSIZE);
1152 AbstractJEuclidElement.DEPRECATED_ATTRIBUTES
1153 .add(AbstractJEuclidElement.ATTR_DEPRECATED_FONTWEIGHT);
1154 AbstractJEuclidElement.DEPRECATED_ATTRIBUTES
1155 .add(AbstractJEuclidElement.ATTR_DEPRECATED_FONTSTYLE);
1156 AbstractJEuclidElement.DEPRECATED_ATTRIBUTES
1157 .add(AbstractJEuclidElement.ATTR_DEPRECATED_FONTFAMILY);
1158
1159 AbstractJEuclidElement.DEPRECATED_ATTRIBUTES
1160 .add(Mo.ATTR_MOVEABLEWRONG);
1161 }
1162 }