001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.internal.forms.widgets;
011:
012: import java.util.ArrayList;
013: import java.util.Hashtable;
014: import java.util.Vector;
015:
016: import org.eclipse.swt.SWT;
017: import org.eclipse.swt.graphics.Color;
018: import org.eclipse.swt.graphics.Font;
019: import org.eclipse.swt.graphics.FontMetrics;
020: import org.eclipse.swt.graphics.GC;
021: import org.eclipse.swt.graphics.Point;
022: import org.eclipse.swt.graphics.Rectangle;
023:
024: import com.ibm.icu.text.BreakIterator;
025:
026: /**
027: * @version 1.0
028: * @author
029: */
030: public class TextSegment extends ParagraphSegment {
031: private String colorId;
032:
033: private String fontId;
034:
035: private String text;
036:
037: protected boolean underline;
038:
039: private boolean wrapAllowed = true;
040:
041: protected Vector areaRectangles = new Vector();
042:
043: private TextFragment[] textFragments;
044:
045: class AreaRectangle {
046: Rectangle rect;
047:
048: int from, to;
049:
050: public AreaRectangle(Rectangle rect, int from, int to) {
051: this .rect = rect;
052: this .from = from;
053: this .to = to;
054: }
055:
056: public boolean contains(int x, int y) {
057: return rect.contains(x, y);
058: }
059:
060: public boolean intersects(Rectangle region) {
061: return rect.intersects(region);
062: }
063:
064: public String getText() {
065: if (from == 0 && to == -1)
066: return TextSegment.this .getText();
067: if (from > 0 && to == -1)
068: return TextSegment.this .getText().substring(from);
069: return TextSegment.this .getText().substring(from, to);
070: }
071: }
072:
073: static class SelectionRange {
074: public int start;
075:
076: public int stop;
077:
078: public SelectionRange() {
079: reset();
080: }
081:
082: public void reset() {
083: start = -1;
084: stop = -1;
085: }
086: }
087:
088: static class TextFragment {
089: short index;
090:
091: short length;
092:
093: public TextFragment(short index, short length) {
094: this .index = index;
095: this .length = length;
096: }
097: }
098:
099: public TextSegment(String text, String fontId) {
100: this (text, fontId, null, true);
101: }
102:
103: public TextSegment(String text, String fontId, String colorId) {
104: this (text, fontId, colorId, true);
105: }
106:
107: public TextSegment(String text, String fontId, String colorId,
108: boolean wrapAllowed) {
109: this .text = cleanup(text);
110: this .fontId = fontId;
111: this .colorId = colorId;
112: this .wrapAllowed = wrapAllowed;
113: }
114:
115: private String cleanup(String text) {
116: StringBuffer buf = new StringBuffer();
117: for (int i = 0; i < text.length(); i++) {
118: char c = text.charAt(i);
119: if (c == '\n' || c == '\r' || c == '\f') {
120: if (i > 0)
121: buf.append(' ');
122: } else
123: buf.append(c);
124: }
125: return buf.toString();
126: }
127:
128: public void setWordWrapAllowed(boolean value) {
129: wrapAllowed = value;
130: }
131:
132: public boolean isWordWrapAllowed() {
133: return wrapAllowed;
134: }
135:
136: public boolean isSelectable() {
137: return false;
138: }
139:
140: public String getColorId() {
141: return colorId;
142: }
143:
144: public String getText() {
145: return text;
146: }
147:
148: void setText(String text) {
149: this .text = cleanup(text);
150: textFragments = null;
151: }
152:
153: void setColorId(String colorId) {
154: this .colorId = colorId;
155: }
156:
157: void setFontId(String fontId) {
158: this .fontId = fontId;
159: textFragments = null;
160: }
161:
162: public boolean contains(int x, int y) {
163: for (int i = 0; i < areaRectangles.size(); i++) {
164: AreaRectangle ar = (AreaRectangle) areaRectangles.get(i);
165: if (ar.contains(x, y))
166: return true;
167: if (i < areaRectangles.size() - 1) {
168: // test the gap
169: Rectangle top = ar.rect;
170: Rectangle bot = ((AreaRectangle) areaRectangles
171: .get(i + 1)).rect;
172: if (y >= top.y + top.height && y < bot.y) {
173: // in the gap
174: int left = Math.max(top.x, bot.x);
175: int right = Math.min(top.x + top.width, bot.x
176: + bot.width);
177: if (x >= left && x <= right) {
178: return true;
179: }
180: }
181: }
182: }
183: return false;
184: }
185:
186: public boolean intersects(Rectangle rect) {
187: for (int i = 0; i < areaRectangles.size(); i++) {
188: AreaRectangle ar = (AreaRectangle) areaRectangles.get(i);
189: if (ar.intersects(rect))
190: return true;
191: if (i < areaRectangles.size() - 1) {
192: // test the gap
193: Rectangle top = ar.rect;
194: Rectangle bot = ((AreaRectangle) areaRectangles
195: .get(i + 1)).rect;
196: if (top.y + top.height < bot.y) {
197: int y = top.y + top.height;
198: int height = bot.y - y;
199: int left = Math.max(top.x, bot.x);
200: int right = Math.min(top.x + top.width, bot.x
201: + bot.width);
202: Rectangle gap = new Rectangle(left, y,
203: right - left, height);
204: if (gap.intersects(rect))
205: return true;
206: }
207: }
208: }
209: return false;
210: }
211:
212: public Rectangle getBounds() {
213: int x = 0, y = 0;
214: int width = 0, height = 0;
215:
216: for (int i = 0; i < areaRectangles.size(); i++) {
217: AreaRectangle ar = (AreaRectangle) areaRectangles.get(i);
218: if (i == 0) {
219: x = ar.rect.x;
220: y = ar.rect.y;
221: } else
222: x = Math.min(ar.rect.x, x);
223: width = Math.max(ar.rect.width, width);
224: height += ar.rect.height;
225: }
226: return new Rectangle(x, y, width, height);
227: }
228:
229: public boolean advanceLocator(GC gc, int wHint, Locator locator,
230: Hashtable objectTable, boolean computeHeightOnly) {
231: Font oldFont = null;
232: if (fontId != null) {
233: oldFont = gc.getFont();
234: Font newFont = (Font) objectTable.get(fontId);
235: if (newFont != null)
236: gc.setFont(newFont);
237: }
238: FontMetrics fm = gc.getFontMetrics();
239: int lineHeight = fm.getHeight();
240: boolean newLine = false;
241:
242: if (wHint == SWT.DEFAULT || !wrapAllowed) {
243: Point extent = gc.textExtent(text);
244: int totalExtent = locator.x + extent.x;
245: if (isSelectable())
246: totalExtent += 1;
247:
248: if (wHint != SWT.DEFAULT && totalExtent > wHint) {
249: // new line
250: locator.x = locator.indent;
251: locator.y += locator.rowHeight;
252: if (computeHeightOnly)
253: locator.collectHeights();
254: locator.rowHeight = 0;
255: locator.leading = 0;
256: newLine = true;
257: }
258: int width = extent.x;
259: if (isSelectable())
260: width += 1;
261: locator.x += width;
262: locator.width = locator.indent + width;
263: locator.rowHeight = Math.max(locator.rowHeight, extent.y);
264: locator.leading = Math
265: .max(locator.leading, fm.getLeading());
266: return newLine;
267: }
268:
269: computeTextFragments(gc);
270:
271: int width = 0;
272: Point lineExtent = new Point(0, 0);
273:
274: for (int i = 0; i < textFragments.length; i++) {
275: TextFragment textFragment = textFragments[i];
276: int currentExtent = locator.x + lineExtent.x;
277:
278: if (isSelectable())
279: currentExtent += 1;
280:
281: if (currentExtent + textFragment.length > wHint) {
282: // overflow
283: int lineWidth = currentExtent;
284: locator.rowHeight = Math.max(locator.rowHeight,
285: lineExtent.y);
286: locator.leading = Math.max(locator.leading, fm
287: .getLeading());
288: if (computeHeightOnly)
289: locator.collectHeights();
290: locator.x = locator.indent;
291: locator.y += locator.rowHeight;
292: locator.rowHeight = 0;
293: locator.leading = 0;
294: lineExtent.x = 0;
295: lineExtent.y = 0;
296: width = Math.max(width, lineWidth);
297: newLine = true;
298: }
299: lineExtent.x += textFragment.length;
300: lineExtent.y = Math.max(lineHeight, lineExtent.y);
301: }
302: int lineWidth = lineExtent.x;
303: if (isSelectable())
304: lineWidth += 1;
305: locator.x += lineWidth;
306: locator.width = width;
307: locator.rowHeight = Math.max(locator.rowHeight, lineExtent.y);
308: locator.leading = Math.max(locator.leading, fm.getLeading());
309: if (oldFont != null) {
310: gc.setFont(oldFont);
311: }
312: return newLine;
313: }
314:
315: /**
316: * @param gc
317: * @param width
318: * @param locator
319: * @param selected
320: * @param selData
321: * @param color
322: * @param fm
323: * @param lineHeight
324: * @param descent
325: */
326: private void layoutWithoutWrapping(GC gc, int width,
327: Locator locator, boolean selected, FontMetrics fm,
328: int lineHeight, int descent) {
329: Point extent = gc.textExtent(text);
330: int ewidth = extent.x;
331: if (isSelectable())
332: ewidth += 1;
333: if (locator.x + ewidth > width - locator.marginWidth) {
334: // new line
335: locator.resetCaret();
336: locator.y += locator.rowHeight;
337: locator.rowHeight = 0;
338: locator.rowCounter++;
339: }
340: int ly = locator.getBaseline(fm.getHeight() - fm.getLeading());
341: //int lineY = ly + lineHeight - descent + 1;
342: Rectangle br = new Rectangle(locator.x, ly, ewidth, lineHeight
343: - descent + 3);
344: areaRectangles.add(new AreaRectangle(br, 0, -1));
345: locator.x += ewidth;
346: locator.width = ewidth;
347: locator.rowHeight = Math.max(locator.rowHeight, extent.y);
348: }
349:
350: protected int convertOffsetToStringIndex(GC gc, String s, int x,
351: int swidth, int selOffset) {
352: int index = s.length();
353: while (index > 0 && x + swidth > selOffset) {
354: index--;
355: String ss = s.substring(0, index);
356: swidth = gc.textExtent(ss).x;
357: }
358: return index;
359: }
360:
361: public void paintFocus(GC gc, Color bg, Color fg, boolean selected,
362: Rectangle repaintRegion) {
363: if (areaRectangles == null)
364: return;
365: for (int i = 0; i < areaRectangles.size(); i++) {
366: AreaRectangle areaRectangle = (AreaRectangle) areaRectangles
367: .get(i);
368: Rectangle br = areaRectangle.rect;
369: int bx = br.x;
370: int by = br.y;
371: if (repaintRegion != null) {
372: bx -= repaintRegion.x;
373: by -= repaintRegion.y;
374: }
375: if (selected) {
376: gc.setBackground(bg);
377: gc.setForeground(fg);
378: gc.drawFocus(bx, by, br.width, br.height);
379: } else {
380: gc.setForeground(bg);
381: gc.drawRectangle(bx, by, br.width - 1, br.height - 1);
382: }
383: }
384: }
385:
386: public void paint(GC gc, boolean hover, Hashtable resourceTable,
387: boolean selected, SelectionData selData,
388: Rectangle repaintRegion) {
389: this .paint(gc, hover, resourceTable, selected, false, selData,
390: repaintRegion);
391: }
392:
393: protected void paint(GC gc, boolean hover, Hashtable resourceTable,
394: boolean selected, boolean rollover, SelectionData selData,
395: Rectangle repaintRegion) {
396: Font oldFont = null;
397: Color oldColor = null;
398: Color oldBg = null;
399:
400: // apply segment-specific font, color and background
401: if (fontId != null) {
402: oldFont = gc.getFont();
403: Font newFont = (Font) resourceTable.get(fontId);
404: if (newFont != null)
405: gc.setFont(newFont);
406: }
407: if (!hover && colorId != null) {
408: oldColor = gc.getForeground();
409: Color newColor = (Color) resourceTable.get(colorId);
410: if (newColor != null)
411: gc.setForeground(newColor);
412: }
413: oldBg = gc.getBackground();
414:
415: FontMetrics fm = gc.getFontMetrics();
416: int lineHeight = fm.getHeight();
417: int descent = fm.getDescent();
418:
419: // paint area rectangles of the segment
420: for (int i = 0; i < areaRectangles.size(); i++) {
421: AreaRectangle areaRectangle = (AreaRectangle) areaRectangles
422: .get(i);
423: Rectangle rect = areaRectangle.rect;
424: String text = areaRectangle.getText();
425: Point extent = gc.textExtent(text);
426: int textX = rect.x + (isSelectable() ? 1 : 0);
427: int lineY = rect.y + lineHeight - descent + 1;
428: paintString(gc, text, extent.x, textX, rect.y, lineY,
429: selData, rect, hover, rollover, repaintRegion);
430: if (selected) {
431: int fx = rect.x;
432: int fy = rect.y;
433: if (repaintRegion != null) {
434: fx -= repaintRegion.x;
435: fy -= repaintRegion.y;
436: }
437: //To avoid partially cancelling the focus by painting over
438: //X-ORed pixels, first cancel it yourself
439: Color fg = gc.getForeground();
440: gc.setForeground(oldBg);
441: gc.drawRectangle(fx, fy, rect.width - 1,
442: rect.height - 1);
443: gc.setForeground(fg);
444: gc.drawFocus(fx, fy, rect.width, rect.height);
445: }
446: }
447: // restore GC resources
448: if (oldFont != null) {
449: gc.setFont(oldFont);
450: }
451: if (oldColor != null) {
452: gc.setForeground(oldColor);
453: }
454: if (oldBg != null) {
455: gc.setBackground(oldBg);
456: }
457: }
458:
459: public void computeSelection(GC gc, Hashtable resourceTable,
460: SelectionData selData) {
461: Font oldFont = null;
462:
463: if (fontId != null) {
464: oldFont = gc.getFont();
465: Font newFont = (Font) resourceTable.get(fontId);
466: if (newFont != null)
467: gc.setFont(newFont);
468: }
469:
470: for (int i = 0; i < areaRectangles.size(); i++) {
471: AreaRectangle areaRectangle = (AreaRectangle) areaRectangles
472: .get(i);
473: Rectangle rect = areaRectangle.rect;
474: String text = areaRectangle.getText();
475: Point extent = gc.textExtent(text);
476: computeSelection(gc, text, extent.x, selData, rect);
477: }
478: // restore GC resources
479: if (oldFont != null) {
480: gc.setFont(oldFont);
481: }
482: }
483:
484: private void paintString(GC gc, String s, int swidth, int x, int y,
485: int lineY, SelectionData selData, Rectangle bounds,
486: boolean hover, boolean rolloverMode, Rectangle repaintRegion) {
487: // repaints one area rectangle
488: if (selData != null && selData.isEnclosed()) {
489: Color savedBg = gc.getBackground();
490: Color savedFg = gc.getForeground();
491: int leftOffset = selData.getLeftOffset(bounds.height);
492: int rightOffset = selData.getRightOffset(bounds.height);
493: boolean firstRow = selData.isFirstSelectionRow(bounds.y,
494: bounds.height);
495: boolean lastRow = selData.isLastSelectionRow(bounds.y,
496: bounds.height);
497: boolean selectedRow = selData.isSelectedRow(bounds.y,
498: bounds.height);
499:
500: int sstart = -1;
501: int sstop = -1;
502:
503: if ((firstRow && x + swidth < leftOffset)
504: || (lastRow && x > rightOffset)) {
505: paintStringSegment(gc, s, gc.textExtent(s).x, x, y,
506: lineY, hover, rolloverMode, repaintRegion);
507: return;
508: }
509:
510: if (firstRow && bounds.x + swidth > leftOffset) {
511: sstart = convertOffsetToStringIndex(gc, s, bounds.x,
512: swidth, leftOffset);
513: }
514: if (lastRow && bounds.x + swidth > rightOffset) {
515: sstop = convertOffsetToStringIndex(gc, s, bounds.x,
516: swidth, rightOffset);
517: }
518:
519: if (firstRow && sstart != -1) {
520: String left = s.substring(0, sstart);
521: int width = gc.textExtent(left).x;
522: paintStringSegment(gc, left, width, x, y, lineY, hover,
523: rolloverMode, repaintRegion);
524: x += width;
525: }
526: if (selectedRow) {
527: int lindex = sstart != -1 ? sstart : 0;
528: int rindex = sstop != -1 ? sstop : s.length();
529: String mid = s.substring(lindex, rindex);
530: Point extent = gc.textExtent(mid);
531: gc.setForeground(selData.fg);
532: gc.setBackground(selData.bg);
533: gc.fillRectangle(x, y, extent.x, extent.y);
534: paintStringSegment(gc, mid, extent.x, x, y, lineY,
535: hover, rolloverMode, repaintRegion);
536: x += extent.x;
537: gc.setForeground(savedFg);
538: gc.setBackground(savedBg);
539: } else {
540: paintStringSegment(gc, s, gc.textExtent(s).x, x, y,
541: lineY, hover, rolloverMode, repaintRegion);
542: }
543: if (lastRow && sstop != -1) {
544: String right = s.substring(sstop);
545: paintStringSegment(gc, right, gc.textExtent(right).x,
546: x, y, lineY, hover, rolloverMode, repaintRegion);
547: }
548: } else {
549: paintStringSegment(gc, s, gc.textExtent(s).x, x, y, lineY,
550: hover, rolloverMode, repaintRegion);
551: }
552: }
553:
554: private void computeSelection(GC gc, String s, int swidth,
555: SelectionData selData, Rectangle bounds) {
556: int leftOffset = selData.getLeftOffset(bounds.height);
557: int rightOffset = selData.getRightOffset(bounds.height);
558: boolean firstRow = selData.isFirstSelectionRow(bounds.y,
559: bounds.height);
560: boolean lastRow = selData.isLastSelectionRow(bounds.y,
561: bounds.height);
562: boolean selectedRow = selData.isSelectedRow(bounds.y,
563: bounds.height);
564:
565: int sstart = -1;
566: int sstop = -1;
567:
568: if (firstRow && bounds.x + swidth > leftOffset) {
569: sstart = convertOffsetToStringIndex(gc, s, bounds.x,
570: swidth, leftOffset);
571: }
572: if (lastRow && bounds.x + swidth > rightOffset) {
573: sstop = convertOffsetToStringIndex(gc, s, bounds.x, swidth,
574: rightOffset);
575: }
576:
577: if (selectedRow) {
578: int lindex = sstart != -1 ? sstart : 0;
579: int rindex = sstop != -1 ? sstop : s.length();
580: String mid = s.substring(lindex, rindex);
581: selData.addSegment(mid);
582: }
583: }
584:
585: /**
586: * @param gc
587: * @param s
588: * @param x
589: * @param y
590: * @param lineY
591: * @param hover
592: * @param rolloverMode
593: */
594: private void paintStringSegment(GC gc, String s, int swidth, int x,
595: int y, int lineY, boolean hover, boolean rolloverMode,
596: Rectangle repaintRegion) {
597: boolean reverse = false;
598: int clipX = x;
599: int clipY = y;
600: int clipLineY = lineY;
601: if (repaintRegion != null) {
602: clipX -= repaintRegion.x;
603: clipY -= repaintRegion.y;
604: clipLineY -= repaintRegion.y;
605: }
606: if (underline || hover || rolloverMode) {
607: if (rolloverMode && !hover)
608: reverse = true;
609: }
610: if (reverse) {
611: drawUnderline(gc, swidth, clipX, clipLineY, hover,
612: rolloverMode);
613: gc.drawString(s, clipX, clipY, false);
614: } else {
615: gc.drawString(s, clipX, clipY, false);
616: drawUnderline(gc, swidth, clipX, clipLineY, hover,
617: rolloverMode);
618: }
619: }
620:
621: private void drawUnderline(GC gc, int swidth, int x, int y,
622: boolean hover, boolean rolloverMode) {
623: if (underline || hover || rolloverMode) {
624: Color saved = null;
625: if (rolloverMode && !hover) {
626: saved = gc.getForeground();
627: gc.setForeground(gc.getBackground());
628: }
629: gc.drawLine(x, y, x + swidth - 1, y);
630: if (saved != null)
631: gc.setForeground(saved);
632: }
633: }
634:
635: /*
636: * (non-Javadoc)
637: *
638: * @see org.eclipse.ui.internal.forms.widgets.ParagraphSegment#layout(org.eclipse.swt.graphics.GC,
639: * int, org.eclipse.ui.internal.forms.widgets.Locator,
640: * java.util.Hashtable, boolean,
641: * org.eclipse.ui.internal.forms.widgets.SelectionData)
642: */
643: public void layout(GC gc, int width, Locator locator,
644: Hashtable resourceTable, boolean selected) {
645: Font oldFont = null;
646:
647: areaRectangles.clear();
648:
649: if (fontId != null) {
650: oldFont = gc.getFont();
651: Font newFont = (Font) resourceTable.get(fontId);
652: if (newFont != null)
653: gc.setFont(newFont);
654: }
655: FontMetrics fm = gc.getFontMetrics();
656: int lineHeight = fm.getHeight();
657: int descent = fm.getDescent();
658:
659: if (!wrapAllowed) {
660: layoutWithoutWrapping(gc, width, locator, selected, fm,
661: lineHeight, descent);
662: } else {
663: int lineStart = 0;
664: int lastLoc = 0;
665: Point lineExtent = new Point(0, 0);
666: computeTextFragments(gc);
667: int rightEdge = width - locator.marginWidth;
668: for (int i = 0; i < textFragments.length; i++) {
669: TextFragment fragment = textFragments[i];
670: int breakLoc = fragment.index;
671: if (breakLoc == 0)
672: continue;
673: if (locator.x + lineExtent.x + fragment.length > rightEdge) {
674: // overflow
675: int lineWidth = locator.x + lineExtent.x;
676: if (isSelectable())
677: lineWidth += 1;
678: int ly = locator.getBaseline(lineHeight
679: - fm.getLeading());
680: Rectangle br = new Rectangle(
681: isSelectable() ? locator.x - 1 : locator.x,
682: ly, isSelectable() ? lineExtent.x + 1
683: : lineExtent.x, lineHeight
684: - descent + 3);
685: areaRectangles.add(new AreaRectangle(br, lineStart,
686: lastLoc));
687:
688: locator.rowHeight = Math.max(locator.rowHeight,
689: lineExtent.y);
690: locator.resetCaret();
691: if (isSelectable())
692: locator.x += 1;
693: locator.y += locator.rowHeight;
694: locator.rowCounter++;
695: locator.rowHeight = 0;
696: lineStart = lastLoc;
697: lineExtent.x = 0;
698: lineExtent.y = 0;
699: }
700: lastLoc = breakLoc;
701: lineExtent.x += fragment.length;
702: lineExtent.y = Math.max(lineHeight, lineExtent.y);
703: }
704: //String lastLine = text.substring(lineStart, lastLoc);
705: int ly = locator.getBaseline(lineHeight - fm.getLeading());
706: int lastWidth = lineExtent.x;
707: if (isSelectable())
708: lastWidth += 1;
709: Rectangle br = new Rectangle(isSelectable() ? locator.x - 1
710: : locator.x, ly, isSelectable() ? lineExtent.x + 1
711: : lineExtent.x, lineHeight - descent + 3);
712: //int lineY = ly + lineHeight - descent + 1;
713: areaRectangles
714: .add(new AreaRectangle(br, lineStart, lastLoc));
715: locator.x += lastWidth;
716: locator.rowHeight = Math.max(locator.rowHeight,
717: lineExtent.y);
718: }
719: if (oldFont != null) {
720: gc.setFont(oldFont);
721: }
722: }
723:
724: private void computeTextFragments(GC gc) {
725: if (textFragments != null)
726: return;
727: ArrayList list = new ArrayList();
728: BreakIterator wb = BreakIterator.getLineInstance();
729: wb.setText(getText());
730: int cursor = 0;
731: for (int loc = wb.first(); loc != BreakIterator.DONE; loc = wb
732: .next()) {
733: if (loc == 0)
734: continue;
735: String word = text.substring(cursor, loc);
736: Point extent = gc.textExtent(word);
737: list.add(new TextFragment((short) loc, (short) extent.x));
738: cursor = loc;
739: }
740: textFragments = (TextFragment[]) list
741: .toArray(new TextFragment[list.size()]);
742: }
743:
744: public void clearCache(String fontId) {
745: if (fontId == null
746: && (this.fontId == null || this.fontId
747: .equals(FormTextModel.BOLD_FONT_ID)))
748: textFragments = null;
749: else if (fontId != null && this.fontId != null
750: && fontId.equals(this.fontId))
751: textFragments = null;
752: }
753: }
|