< prev index next >

src/java.desktop/share/classes/sun/font/GlyphLayout.java

Print this page




  79 import java.util.concurrent.ConcurrentHashMap;
  80 
  81 import static java.lang.Character.*;
  82 
  83 public final class GlyphLayout {
  84     // data for glyph vector
  85     private GVData _gvdata;
  86 
  87     // cached glyph layout data for reuse
  88     private static volatile GlyphLayout cache;  // reusable
  89 
  90     private LayoutEngineFactory _lef;  // set when get is called, unset when done is called
  91     private TextRecord _textRecord;    // the text we're working on, used by iterators
  92     private ScriptRun _scriptRuns;     // iterator over script runs
  93     private FontRunIterator _fontRuns; // iterator over physical fonts in a composite
  94     private int _ercount;
  95     private ArrayList<EngineRecord> _erecords;
  96     private Point2D.Float _pt;
  97     private FontStrikeDesc _sd;
  98     private float[] _mat;

  99     private int _typo_flags;
 100     private int _offset;
 101 
 102     public static final class LayoutEngineKey {
 103         private Font2D font;
 104         private int script;
 105         private int lang;
 106 
 107         LayoutEngineKey() {
 108         }
 109 
 110         LayoutEngineKey(Font2D font, int script, int lang) {
 111             init(font, script, lang);
 112         }
 113 
 114         void init(Font2D font, int script, int lang) {
 115             this.font = font;
 116             this.script = script;
 117             this.lang = lang;
 118         }


 155     public static interface LayoutEngineFactory {
 156         /**
 157          * Given a font, script, and language, determine a layout engine to use.
 158          */
 159         public LayoutEngine getEngine(Font2D font, int script, int lang);
 160 
 161         /**
 162          * Given a key, determine a layout engine to use.
 163          */
 164         public LayoutEngine getEngine(LayoutEngineKey key);
 165     }
 166 
 167     public static interface LayoutEngine {
 168         /**
 169          * Given a strike descriptor, text, rtl flag, and starting point, append information about
 170          * glyphs, positions, and character indices to the glyphvector data, and advance the point.
 171          *
 172          * If the GVData does not have room for the glyphs, throws an IndexOutOfBoundsException and
 173          * leave pt and the gvdata unchanged.
 174          */
 175         public void layout(FontStrikeDesc sd, float[] mat, int gmask,
 176                            int baseIndex, TextRecord text, int typo_flags, Point2D.Float pt, GVData data);
 177     }
 178 
 179     /**
 180      * Return a new instance of GlyphLayout, using the provided layout engine factory.
 181      * If null, the system layout engine factory will be used.
 182      */
 183     public static GlyphLayout get(LayoutEngineFactory lef) {
 184         if (lef == null) {
 185             lef = SunLayoutEngine.instance();
 186         }
 187         GlyphLayout result = null;
 188         synchronized(GlyphLayout.class) {
 189             if (cache != null) {
 190                 result = cache;
 191                 cache = null;
 192             }
 193         }
 194         if (result == null) {
 195             result = new GlyphLayout();


 369         init(count);
 370 
 371         // need to set after init
 372         // go through the back door for this
 373         if (font.hasLayoutAttributes()) {
 374             AttributeValues values = ((AttributeMap)font.getAttributes()).getValues();
 375             if (values.getKerning() != 0) _typo_flags |= 0x1;
 376             if (values.getLigatures() != 0) _typo_flags |= 0x2;
 377         }
 378 
 379         _offset = offset;
 380 
 381         // use cache now - can we use the strike cache for this?
 382 
 383         SDCache txinfo = SDCache.get(font, frc);
 384         _mat[0] = (float)txinfo.gtx.getScaleX();
 385         _mat[1] = (float)txinfo.gtx.getShearY();
 386         _mat[2] = (float)txinfo.gtx.getShearX();
 387         _mat[3] = (float)txinfo.gtx.getScaleY();
 388         _pt.setLocation(txinfo.delta);

 389 
 390         int lim = offset + count;
 391 
 392         int min = 0;
 393         int max = text.length;
 394         if (flags != 0) {
 395             if ((flags & Font.LAYOUT_RIGHT_TO_LEFT) != 0) {
 396               _typo_flags |= 0x80000000; // RTL
 397             }
 398 
 399             if ((flags & Font.LAYOUT_NO_START_CONTEXT) != 0) {
 400                 min = offset;
 401             }
 402 
 403             if ((flags & Font.LAYOUT_NO_LIMIT_CONTEXT) != 0) {
 404                 max = lim;
 405             }
 406         }
 407 
 408         int lang = -1; // default for now


 665                     isLowSurrogate(_textRecord.text[i+1])) {
 666                     // rare case
 667                     ch = toCodePoint((char)ch,_textRecord.text[++i]); // inc
 668                 }
 669                 int gc = getType(ch);
 670                 if (gc == NON_SPACING_MARK ||
 671                     gc == ENCLOSING_MARK ||
 672                     gc == COMBINING_SPACING_MARK) { // could do range test also
 673 
 674                     this.eflags = 0x4;
 675                     break;
 676                 }
 677             }
 678 
 679             this.engine = _lef.getEngine(key); // flags?
 680         }
 681 
 682         void layout() {
 683             _textRecord.start = start;
 684             _textRecord.limit = limit;
 685             engine.layout(_sd, _mat, gmask, start - _offset, _textRecord,
 686                           _typo_flags | eflags, _pt, _gvdata);
 687         }
 688     }
 689 }


  79 import java.util.concurrent.ConcurrentHashMap;
  80 
  81 import static java.lang.Character.*;
  82 
  83 public final class GlyphLayout {
  84     // data for glyph vector
  85     private GVData _gvdata;
  86 
  87     // cached glyph layout data for reuse
  88     private static volatile GlyphLayout cache;  // reusable
  89 
  90     private LayoutEngineFactory _lef;  // set when get is called, unset when done is called
  91     private TextRecord _textRecord;    // the text we're working on, used by iterators
  92     private ScriptRun _scriptRuns;     // iterator over script runs
  93     private FontRunIterator _fontRuns; // iterator over physical fonts in a composite
  94     private int _ercount;
  95     private ArrayList<EngineRecord> _erecords;
  96     private Point2D.Float _pt;
  97     private FontStrikeDesc _sd;
  98     private float[] _mat;
  99     private float ptSize;
 100     private int _typo_flags;
 101     private int _offset;
 102 
 103     public static final class LayoutEngineKey {
 104         private Font2D font;
 105         private int script;
 106         private int lang;
 107 
 108         LayoutEngineKey() {
 109         }
 110 
 111         LayoutEngineKey(Font2D font, int script, int lang) {
 112             init(font, script, lang);
 113         }
 114 
 115         void init(Font2D font, int script, int lang) {
 116             this.font = font;
 117             this.script = script;
 118             this.lang = lang;
 119         }


 156     public static interface LayoutEngineFactory {
 157         /**
 158          * Given a font, script, and language, determine a layout engine to use.
 159          */
 160         public LayoutEngine getEngine(Font2D font, int script, int lang);
 161 
 162         /**
 163          * Given a key, determine a layout engine to use.
 164          */
 165         public LayoutEngine getEngine(LayoutEngineKey key);
 166     }
 167 
 168     public static interface LayoutEngine {
 169         /**
 170          * Given a strike descriptor, text, rtl flag, and starting point, append information about
 171          * glyphs, positions, and character indices to the glyphvector data, and advance the point.
 172          *
 173          * If the GVData does not have room for the glyphs, throws an IndexOutOfBoundsException and
 174          * leave pt and the gvdata unchanged.
 175          */
 176         public void layout(FontStrikeDesc sd, float[] mat, float ptSize, int gmask,
 177                            int baseIndex, TextRecord text, int typo_flags, Point2D.Float pt, GVData data);
 178     }
 179 
 180     /**
 181      * Return a new instance of GlyphLayout, using the provided layout engine factory.
 182      * If null, the system layout engine factory will be used.
 183      */
 184     public static GlyphLayout get(LayoutEngineFactory lef) {
 185         if (lef == null) {
 186             lef = SunLayoutEngine.instance();
 187         }
 188         GlyphLayout result = null;
 189         synchronized(GlyphLayout.class) {
 190             if (cache != null) {
 191                 result = cache;
 192                 cache = null;
 193             }
 194         }
 195         if (result == null) {
 196             result = new GlyphLayout();


 370         init(count);
 371 
 372         // need to set after init
 373         // go through the back door for this
 374         if (font.hasLayoutAttributes()) {
 375             AttributeValues values = ((AttributeMap)font.getAttributes()).getValues();
 376             if (values.getKerning() != 0) _typo_flags |= 0x1;
 377             if (values.getLigatures() != 0) _typo_flags |= 0x2;
 378         }
 379 
 380         _offset = offset;
 381 
 382         // use cache now - can we use the strike cache for this?
 383 
 384         SDCache txinfo = SDCache.get(font, frc);
 385         _mat[0] = (float)txinfo.gtx.getScaleX();
 386         _mat[1] = (float)txinfo.gtx.getShearY();
 387         _mat[2] = (float)txinfo.gtx.getShearX();
 388         _mat[3] = (float)txinfo.gtx.getScaleY();
 389         _pt.setLocation(txinfo.delta);
 390         ptSize = font.getSize2D();
 391 
 392         int lim = offset + count;
 393 
 394         int min = 0;
 395         int max = text.length;
 396         if (flags != 0) {
 397             if ((flags & Font.LAYOUT_RIGHT_TO_LEFT) != 0) {
 398               _typo_flags |= 0x80000000; // RTL
 399             }
 400 
 401             if ((flags & Font.LAYOUT_NO_START_CONTEXT) != 0) {
 402                 min = offset;
 403             }
 404 
 405             if ((flags & Font.LAYOUT_NO_LIMIT_CONTEXT) != 0) {
 406                 max = lim;
 407             }
 408         }
 409 
 410         int lang = -1; // default for now


 667                     isLowSurrogate(_textRecord.text[i+1])) {
 668                     // rare case
 669                     ch = toCodePoint((char)ch,_textRecord.text[++i]); // inc
 670                 }
 671                 int gc = getType(ch);
 672                 if (gc == NON_SPACING_MARK ||
 673                     gc == ENCLOSING_MARK ||
 674                     gc == COMBINING_SPACING_MARK) { // could do range test also
 675 
 676                     this.eflags = 0x4;
 677                     break;
 678                 }
 679             }
 680 
 681             this.engine = _lef.getEngine(key); // flags?
 682         }
 683 
 684         void layout() {
 685             _textRecord.start = start;
 686             _textRecord.limit = limit;
 687             engine.layout(_sd, _mat, ptSize, gmask, start - _offset, _textRecord,
 688                           _typo_flags | eflags, _pt, _gvdata);
 689         }
 690     }
 691 }
< prev index next >