This may well be a fix to the "Improper line wrapping" bug. The fix
is basically that we use our own special ViewFactory, with a new
subclass of LabelView (the view RTFEditorKit uses for the nitty
gritty) that is aware of Tibetan.
There are a couple of nasty hacks still here, and Swing's
documentation for doing what I did was quite poor. I searched the web
for hours, read the Javadocs and the tutorials, and consulted a Swing
reference book, but I still don't have tremendous confidence in this
solution. If it fundamentally doesn't work, though, we have to define
our own first-class Document, Element hierarchy, ViewFactory, Views,
and EditorKit. So let's hope it *does* work fundamentally.
I can't say for sure if this even works, as I have yet to run this
code on a machine where Jskad works properly. I had major trouble
installing the TMW fonts on Linux, and have yet to resolve it, even
after verifying via xlsfonts that the fonts were installed and then
changing TibetanMachineWeb.java to look for them. Because I haven't
tested this yet, a lot of nasty code is tagged 'DLC' and commented
out.
2002-10-28 03:08:04 +00:00
|
|
|
/*
|
|
|
|
The contents of this file are subject to the THDL Open Community License
|
|
|
|
Version 1.0 (the "License"); you may not use this file except in compliance
|
|
|
|
with the License. You may obtain a copy of the License on the THDL web site
|
|
|
|
(http://www.thdl.org/).
|
|
|
|
|
|
|
|
Software distributed under the License is distributed on an "AS IS" basis,
|
|
|
|
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|
|
|
|
License for the specific terms governing rights and limitations under the
|
|
|
|
License.
|
|
|
|
|
|
|
|
The Initial Developer of this software is the Tibetan and Himalayan Digital
|
|
|
|
Library (THDL). Portions created by the THDL are Copyright 2001 THDL.
|
|
|
|
All Rights Reserved.
|
|
|
|
|
|
|
|
Contributor(s): ______________________________________.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package org.thdl.tib.text;
|
|
|
|
|
|
|
|
import javax.swing.*;
|
|
|
|
import javax.swing.text.*;
|
|
|
|
|
|
|
|
/** A TibetanLabelView is a LabelView that has its own idea, informed
|
|
|
|
* by its knowledge of Tibetan, about where a good place to break
|
|
|
|
* text is.
|
|
|
|
*
|
|
|
|
* <p>
|
|
|
|
*
|
|
|
|
* If Character.isWhiteSpace() could be overridden, and if that only
|
|
|
|
* affected breaking (which is doubtful), we wouldn't need this--we'd
|
|
|
|
* just treat Tibetan punctuation there. We might also like to
|
|
|
|
* override java.awt.font.GlyphMetrics idea of whitespace (though I'm
|
|
|
|
* not sure what consequences besides breaking that might have). But
|
|
|
|
* we can't override either since they're final. So we roll our own.
|
|
|
|
*
|
|
|
|
* @author David Chandler */
|
|
|
|
class TibetanLabelView extends LabelView {
|
2002-10-28 04:12:49 +00:00
|
|
|
private boolean logging;
|
This may well be a fix to the "Improper line wrapping" bug. The fix
is basically that we use our own special ViewFactory, with a new
subclass of LabelView (the view RTFEditorKit uses for the nitty
gritty) that is aware of Tibetan.
There are a couple of nasty hacks still here, and Swing's
documentation for doing what I did was quite poor. I searched the web
for hours, read the Javadocs and the tutorials, and consulted a Swing
reference book, but I still don't have tremendous confidence in this
solution. If it fundamentally doesn't work, though, we have to define
our own first-class Document, Element hierarchy, ViewFactory, Views,
and EditorKit. So let's hope it *does* work fundamentally.
I can't say for sure if this even works, as I have yet to run this
code on a machine where Jskad works properly. I had major trouble
installing the TMW fonts on Linux, and have yet to resolve it, even
after verifying via xlsfonts that the fonts were installed and then
changing TibetanMachineWeb.java to look for them. Because I haven't
tested this yet, a lot of nasty code is tagged 'DLC' and commented
out.
2002-10-28 03:08:04 +00:00
|
|
|
/** Creates a new TibetanLabelView. */
|
2002-10-28 04:12:49 +00:00
|
|
|
public TibetanLabelView(Element e, boolean debugLog) {
|
This may well be a fix to the "Improper line wrapping" bug. The fix
is basically that we use our own special ViewFactory, with a new
subclass of LabelView (the view RTFEditorKit uses for the nitty
gritty) that is aware of Tibetan.
There are a couple of nasty hacks still here, and Swing's
documentation for doing what I did was quite poor. I searched the web
for hours, read the Javadocs and the tutorials, and consulted a Swing
reference book, but I still don't have tremendous confidence in this
solution. If it fundamentally doesn't work, though, we have to define
our own first-class Document, Element hierarchy, ViewFactory, Views,
and EditorKit. So let's hope it *does* work fundamentally.
I can't say for sure if this even works, as I have yet to run this
code on a machine where Jskad works properly. I had major trouble
installing the TMW fonts on Linux, and have yet to resolve it, even
after verifying via xlsfonts that the fonts were installed and then
changing TibetanMachineWeb.java to look for them. Because I haven't
tested this yet, a lot of nasty code is tagged 'DLC' and commented
out.
2002-10-28 03:08:04 +00:00
|
|
|
super(e);
|
|
|
|
// FIXME: assert (e == this.getElement())
|
2002-10-28 04:12:49 +00:00
|
|
|
|
|
|
|
logging = debugLog;
|
This may well be a fix to the "Improper line wrapping" bug. The fix
is basically that we use our own special ViewFactory, with a new
subclass of LabelView (the view RTFEditorKit uses for the nitty
gritty) that is aware of Tibetan.
There are a couple of nasty hacks still here, and Swing's
documentation for doing what I did was quite poor. I searched the web
for hours, read the Javadocs and the tutorials, and consulted a Swing
reference book, but I still don't have tremendous confidence in this
solution. If it fundamentally doesn't work, though, we have to define
our own first-class Document, Element hierarchy, ViewFactory, Views,
and EditorKit. So let's hope it *does* work fundamentally.
I can't say for sure if this even works, as I have yet to run this
code on a machine where Jskad works properly. I had major trouble
installing the TMW fonts on Linux, and have yet to resolve it, even
after verifying via xlsfonts that the fonts were installed and then
changing TibetanMachineWeb.java to look for them. Because I haven't
tested this yet, a lot of nasty code is tagged 'DLC' and commented
out.
2002-10-28 03:08:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public int getBreakWeight(int axis, float pos, float len) {
|
|
|
|
if (View.X_AXIS != axis) {
|
|
|
|
// This doesn't impact line wrapping.
|
|
|
|
return super.getBreakWeight(axis, pos, len);
|
|
|
|
} else {
|
|
|
|
int startPos = this.getElement().getStartOffset();
|
|
|
|
|
|
|
|
int boundedPos = getPosNearTheEnd(startPos, pos, len);
|
|
|
|
|
|
|
|
// boundedPos is short, and can be as short as startPos.
|
|
|
|
// I don't know when to say something is good as opposed
|
|
|
|
// to bad, but calling everything bad didn't work so well.
|
|
|
|
// So let's call boundedPos <= startPos bad and everything
|
|
|
|
// else without whitespace or tshegs et cetera good.
|
|
|
|
if (boundedPos <= startPos)
|
|
|
|
return View.BadBreakWeight;
|
|
|
|
|
|
|
|
if (getGoodBreakingLocation(startPos, boundedPos) >= 0)
|
|
|
|
return View.ExcellentBreakWeight;
|
|
|
|
else
|
|
|
|
return View.GoodBreakWeight;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public View breakView(int axis, int p0, float pos, float len) {
|
|
|
|
if (View.X_AXIS != axis) {
|
|
|
|
// This doesn't impact line wrapping.
|
|
|
|
return super.breakView(axis, p0, pos, len);
|
|
|
|
} else {
|
|
|
|
int boundedPos = getPosNearTheEnd(p0, pos, len);
|
|
|
|
|
|
|
|
if (p0 == boundedPos) {
|
|
|
|
// We can't call createFragment safely. Return the
|
|
|
|
// current view.
|
|
|
|
return this;
|
|
|
|
} else {
|
|
|
|
int bloc = getGoodBreakingLocation(p0, boundedPos);
|
|
|
|
int whereToBreak;
|
|
|
|
if (bloc >= 0)
|
|
|
|
whereToBreak = bloc;
|
|
|
|
else
|
|
|
|
whereToBreak = boundedPos;
|
|
|
|
/* Return a new view, a fragment of the current one.
|
|
|
|
* If createFragment isn't smart, we could create
|
|
|
|
* infinitely many views of the same text if we don't
|
|
|
|
* check to see that this new view is actually
|
|
|
|
* different than the current view. */
|
|
|
|
if (this.getStartOffset() != p0
|
|
|
|
|| this.getEndOffset() != whereToBreak) {
|
|
|
|
return createFragment(p0, whereToBreak);
|
|
|
|
} else
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Returns an offset >= 0 if we find a character (FIXME: before
|
|
|
|
* or after?) where breaking would be good. Returns negative
|
|
|
|
* otherwise. */
|
|
|
|
private int getGoodBreakingLocation(int startOffset, int endOffset) {
|
|
|
|
|
|
|
|
// Grab the underlying characters:
|
|
|
|
Segment seggy = this.getText(startOffset, endOffset);
|
|
|
|
|
2002-10-28 04:12:49 +00:00
|
|
|
// Now look for whitespace. Going from the back is what you
|
|
|
|
// want--otherwise, your 2nd line of text will be fuller than
|
|
|
|
// your first.
|
|
|
|
char currentChar = seggy.last();
|
|
|
|
for (; currentChar != Segment.DONE; currentChar = seggy.previous()) {
|
This may well be a fix to the "Improper line wrapping" bug. The fix
is basically that we use our own special ViewFactory, with a new
subclass of LabelView (the view RTFEditorKit uses for the nitty
gritty) that is aware of Tibetan.
There are a couple of nasty hacks still here, and Swing's
documentation for doing what I did was quite poor. I searched the web
for hours, read the Javadocs and the tutorials, and consulted a Swing
reference book, but I still don't have tremendous confidence in this
solution. If it fundamentally doesn't work, though, we have to define
our own first-class Document, Element hierarchy, ViewFactory, Views,
and EditorKit. So let's hope it *does* work fundamentally.
I can't say for sure if this even works, as I have yet to run this
code on a machine where Jskad works properly. I had major trouble
installing the TMW fonts on Linux, and have yet to resolve it, even
after verifying via xlsfonts that the fonts were installed and then
changing TibetanMachineWeb.java to look for them. Because I haven't
tested this yet, a lot of nasty code is tagged 'DLC' and commented
out.
2002-10-28 03:08:04 +00:00
|
|
|
// FIXME: eeek! How do we know when we're dealing with
|
2002-10-28 04:12:49 +00:00
|
|
|
// Tibetan and when we're not? This is styled text, so
|
|
|
|
// where are the attributes etc.? We should find the font
|
|
|
|
// and decide about breaking based on that. Well, we
|
|
|
|
// should if we want a clean solution and don't mind a
|
|
|
|
// little performance hit.
|
|
|
|
//
|
|
|
|
// This question only needs to be answered if you want a
|
|
|
|
// clean solution, I think, because the code below should
|
|
|
|
// work exactly the same. Here's what's up: Even though
|
|
|
|
// we aren't testing to see if we're typing Roman or
|
|
|
|
// Tibetan, a character that's good for a line break in
|
|
|
|
// one is also good in the other. Methinks Tony Duff was
|
|
|
|
// smart like that.
|
|
|
|
//
|
|
|
|
// To be explicit, the test below seems to work perfectly
|
|
|
|
// for both Tibetan and Roman text. (Maybe Roman text
|
|
|
|
// will break after hyphens more quickly, but hey.)
|
|
|
|
//
|
|
|
|
// That said, this is still a FIXME. But note that the
|
|
|
|
// obvious fix will slow things down.
|
|
|
|
|
|
|
|
if (Character.isWhitespace(currentChar) // FIXME: is this OK for Tibetan text? Tony Duff may have made it so, but maybe not. Test!
|
|
|
|
|| TibetanMachineWeb.isTMWFontCharBreakable(currentChar))
|
This may well be a fix to the "Improper line wrapping" bug. The fix
is basically that we use our own special ViewFactory, with a new
subclass of LabelView (the view RTFEditorKit uses for the nitty
gritty) that is aware of Tibetan.
There are a couple of nasty hacks still here, and Swing's
documentation for doing what I did was quite poor. I searched the web
for hours, read the Javadocs and the tutorials, and consulted a Swing
reference book, but I still don't have tremendous confidence in this
solution. If it fundamentally doesn't work, though, we have to define
our own first-class Document, Element hierarchy, ViewFactory, Views,
and EditorKit. So let's hope it *does* work fundamentally.
I can't say for sure if this even works, as I have yet to run this
code on a machine where Jskad works properly. I had major trouble
installing the TMW fonts on Linux, and have yet to resolve it, even
after verifying via xlsfonts that the fonts were installed and then
changing TibetanMachineWeb.java to look for them. Because I haven't
tested this yet, a lot of nasty code is tagged 'DLC' and commented
out.
2002-10-28 03:08:04 +00:00
|
|
|
{
|
2002-10-28 04:12:49 +00:00
|
|
|
// The '+ 1' is because you want to break after a
|
|
|
|
// tsheg or what not rather than before it.
|
|
|
|
int goodPlace = (startOffset + seggy.getIndex()
|
|
|
|
- seggy.getBeginIndex() + 1);
|
|
|
|
if (logging) {
|
|
|
|
String s = new String(seggy.array, seggy.offset, seggy.count);
|
|
|
|
if (!"\n".equals(s)) {
|
|
|
|
System.out.println("TibetanLabelView: found a good break in \""
|
|
|
|
+ new String(seggy.array, seggy.offset, seggy.count)
|
|
|
|
+ "\"; we should break after character "
|
|
|
|
+ (seggy.getIndex() - seggy.getBeginIndex() + 1)
|
|
|
|
+ " (counting begins at one)");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return goodPlace;
|
This may well be a fix to the "Improper line wrapping" bug. The fix
is basically that we use our own special ViewFactory, with a new
subclass of LabelView (the view RTFEditorKit uses for the nitty
gritty) that is aware of Tibetan.
There are a couple of nasty hacks still here, and Swing's
documentation for doing what I did was quite poor. I searched the web
for hours, read the Javadocs and the tutorials, and consulted a Swing
reference book, but I still don't have tremendous confidence in this
solution. If it fundamentally doesn't work, though, we have to define
our own first-class Document, Element hierarchy, ViewFactory, Views,
and EditorKit. So let's hope it *does* work fundamentally.
I can't say for sure if this even works, as I have yet to run this
code on a machine where Jskad works properly. I had major trouble
installing the TMW fonts on Linux, and have yet to resolve it, even
after verifying via xlsfonts that the fonts were installed and then
changing TibetanMachineWeb.java to look for them. Because I haven't
tested this yet, a lot of nasty code is tagged 'DLC' and commented
out.
2002-10-28 03:08:04 +00:00
|
|
|
}
|
|
|
|
}
|
2002-10-28 04:12:49 +00:00
|
|
|
|
|
|
|
// There is no good place. Return a negative number.
|
|
|
|
if (logging) {
|
|
|
|
String s = new String(seggy.array, seggy.offset, seggy.count);
|
|
|
|
if (!"\n".equals(s)) {
|
|
|
|
System.out.println("TibetanLabelView: found NO good break in \""
|
|
|
|
+ new String(seggy.array, seggy.offset, seggy.count)
|
|
|
|
+ "\"");
|
|
|
|
}
|
|
|
|
}
|
This may well be a fix to the "Improper line wrapping" bug. The fix
is basically that we use our own special ViewFactory, with a new
subclass of LabelView (the view RTFEditorKit uses for the nitty
gritty) that is aware of Tibetan.
There are a couple of nasty hacks still here, and Swing's
documentation for doing what I did was quite poor. I searched the web
for hours, read the Javadocs and the tutorials, and consulted a Swing
reference book, but I still don't have tremendous confidence in this
solution. If it fundamentally doesn't work, though, we have to define
our own first-class Document, Element hierarchy, ViewFactory, Views,
and EditorKit. So let's hope it *does* work fundamentally.
I can't say for sure if this even works, as I have yet to run this
code on a machine where Jskad works properly. I had major trouble
installing the TMW fonts on Linux, and have yet to resolve it, even
after verifying via xlsfonts that the fonts were installed and then
changing TibetanMachineWeb.java to look for them. Because I haven't
tested this yet, a lot of nasty code is tagged 'DLC' and commented
out.
2002-10-28 03:08:04 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Returns a position just before or at the position specified by
|
|
|
|
* the three arguments. viewToModel seems like the thing to use,
|
|
|
|
* but we don't have the parameters to pass to it. We can call
|
|
|
|
* GlyphView.GlyphPainter.getBoundedPosition(..) instead, and
|
|
|
|
* its comment mentions viewToModel, so maybe this is actually
|
|
|
|
* better.
|
|
|
|
*/
|
|
|
|
private int getPosNearTheEnd(int startPos, float pos, float len) {
|
|
|
|
// this is provided, and it appears that we'd better use it:
|
|
|
|
checkPainter();
|
|
|
|
|
|
|
|
return this.getGlyphPainter().getBoundedPosition(this, startPos,
|
|
|
|
pos, len);
|
|
|
|
}
|
|
|
|
}
|